如何在Spring中添加带有WebMvcConfigurerAdapter的Filter?

时间:2015-11-01 15:36:34

标签: spring spring-mvc servlet-filters

使用WebApplicationInitializer,我可以轻松地在ServletContext方法中为onStartup()添加过滤器。

如何使用WebMvcConfigurerAdapter添加过滤器?我必须使用XML吗?

ADD 1

为了帮助其他人更轻松地理解Spring Web配置,我绘制了下面的插图。

现在您只需要先了解Spring Web配置背后的rational。然后选择要继承的配置类以及从下面覆盖的方法。

查找它比记住这么多事情要痛苦得多。

enter image description here

关于Spring Web Initialization的一篇很好的文章:

http://www.kubrynski.com/2014/01/understanding-spring-web-initialization.html

ADD 2

根据Tunaki的回复,我查看了AbstractDispatcherServletInitializer。过滤器注册发生在以下代码中:

enter image description here

即使我覆盖绿色getServletFilters()方法,我仍然无法访问Dyanmic的{​​{1}}结果。那么如何按registerServletFilter()配置过滤器?

似乎我addMappingForUrlPatterns()覆盖了整个have to方法。

3 个答案:

答案 0 :(得分:11)

WebMvcConfigurer是一个接口,用于通过@EnableWebMvc自定义启用Spring MVC的基于Java的配置。 WebMvcConfigurerAdapter只是一个为此接口提供默认空方法的适配器。

它不配置DispatcherServlet,这是使用的过滤器。因此,您无法使用WebMvcConfigurer配置servlet过滤器。

要轻松配置过滤器,您可以继承AbstractDispatcherServletInitializer并覆盖getServletFilters()

public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {

    @Override
    protected Filter[] getServletFilters() {
        return new Filter[] { new CharacterEncodingFilter() };
    }

}

如果您想进一步配置过滤器,则必须改为覆盖onStartup

@Override
public void onStartup(ServletContext servletContext) throws ServletException {
    super.onStartup(servletContext);
    servletContext.addFilter("name", CharacterEncodingFilter.class)
                  .addMappingForUrlPatterns(null, false, "/*");
}

答案 1 :(得分:0)

您可以在应用配置中详细访问registerServletFilter()的Dyanmic结果(具体来说,WebApplicationInitializer):

@Override
public void onStartup(ServletContext servletContext) throws ServletException {

    // Create the 'root' Spring application context
    AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

    rootContext.register(
        AppConfig.class,
        SecurityConfiguration.class,
        HibernateConfiguration.class 
    );

    // Add cuatom filters to servletContext
    FilterRegistration.Dynamic filterRegistration = servletContext.addFilter("recaptchaResponseFilter", new RecaptchaResponseFilter());
    filterRegistration.setInitParameter("encoding", "UTF-8");
    filterRegistration.setInitParameter("forceEncoding", "true");
    filterRegistration.addMappingForUrlPatterns(null, true, "/*");

    // Create the dispatcher servlet's Spring application context
    AnnotationConfigWebApplicationContext dispatcherServlet = new AnnotationConfigWebApplicationContext();
    dispatcherServlet.register(MVCConfig.class);

    // Register and map the dispatcher servlet
    ServletRegistration.Dynamic dispatcher = servletContext.addServlet("dispatcher", new DispatcherServlet(dispatcherServlet));
    dispatcher.setLoadOnStartup(1);
    dispatcher.addMapping("/");

答案 2 :(得分:0)

您可以创建在其中实现Filter和@Inject ServletContext的spring bean。 然后在@PostConstruct方法中,您可以使用servletContext.addServlet(“myFilter”,this)注册它们;

public class MyFilter implements Filter {
    @Inject
    private ServletContext servletContext;

    @PostConstruct
    public void init(){
        ServletRegistration.Dynamic filter = servletContext.addServlet("myFilter",this);
        filter.addMapping("/myMapping");
    }
}

不能在使用ContextLoaderListener(rootContext)初始化的rootContext中声明bean,因为servlet 3.0 api禁止对侦听器使用动态注册。 所以它必须在给DispatcherServlet(dispatcherContext)的dispatcherContext中声明

public class MyWebAppInitializer implements WebApplicationInitializer {

   @Override
   public void onStartup(ServletContext container) {
     // Create the 'root' Spring application context
     AnnotationConfigWebApplicationContext rootContext =
       new AnnotationConfigWebApplicationContext();
     rootContext.register(AppConfig.class);

     // Manage the lifecycle of the root application context
     container.addListener(new ContextLoaderListener(rootContext));

     // Create the dispatcher servlet's Spring application context
     AnnotationConfigWebApplicationContext dispatcherContext =
       new AnnotationConfigWebApplicationContext();
     dispatcherContext.register(DispatcherConfig.class);

     // Register and map the dispatcher servlet
     ServletRegistration.Dynamic dispatcher =
       container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
     dispatcher.setLoadOnStartup(1);
     dispatcher.addMapping("/");
   }

}

spring doc