【问题标题】:How to add a Filter with WebMvcConfigurerAdapter in Spring?如何在 Spring 中使用 WebMvcConfigurerAdapter 添加过滤器?
【发布时间】:2016-02-01 12:39:50
【问题描述】:

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

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

添加 1

为了帮助其他人更容易理解 Spring Web Configuration,我画了下图。

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

查找它比记住这么多东西更痛苦。

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

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

添加 2

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

即使我覆盖了绿色的getServletFilters() 方法,我仍然无法访问registerServletFilter()Dyanmic 结果。那么如何通过addMappingForUrlPatterns()配置过滤器呢?

看来我have to 覆盖了整个registerDispatcherServlet() 方法。

【问题讨论】:

  • 过滤器自动映射到DispatcherServlet。如果您需要其他内容,请覆盖 onStartup 方法(不要忘记调用 super.onStartup 并像往常一样自己注册过滤器。这仍然有效......
  • 或者简单地添加另一个实现WebApplicationInitializer的类...可以有多个,不一定只有一个!。

标签: spring spring-mvc servlet-filters


【解决方案1】:

您可以在其中创建实现 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");
    }
}

bean 不能在使用 ContextLoaderListener(rootContext) 初始化的 rootContext 中声明,因为 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

【讨论】:

    【解决方案2】:

    您可以在您的应用配置(特别是WebApplicationInitializer)中访问registerServletFilter() 的动态结果,如下所示:

    @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("/");
    

    【讨论】:

      【解决方案3】:

      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, "/*");
      }
      

      【讨论】:

      • 谢谢。但即使通过扩展AbstractDispatcherServletInitialier,我怎样才能获得FilterRegisteration 对象以便调用addMappingForUrlPatterns()
      • 我的 Add1 仅供参考。我的 Add2 与添加过滤器的问题有关。你可以忽略我的 Add 1。
      • AbstractDispatcherServletInitializer 还需要实现 createServletApplicationContext、getServletMappings 和 createRootApplicationContext,但似乎没有应用过滤器。
      猜你喜欢
      • 2013-11-18
      • 1970-01-01
      • 2019-01-12
      • 2017-11-22
      • 2017-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多