【问题标题】:How to define servlet filter order of execution using annotations in WAR如何使用 WAR 中的注释定义 servlet 过滤器的执行顺序
【发布时间】:2011-09-27 12:09:10
【问题描述】:

如果我们在 WAR 自己的 web.xml 中定义 webapp 特定的 servlet 过滤器,那么过滤器的执行顺序将与它们在 web.xml 中定义的顺序相同。

但是,如果我们使用@WebFilter注解定义这些过滤器,过滤器的执行顺序是什么,我们如何确定执行顺序?

【问题讨论】:

    标签: servlets jakarta-ee web.xml servlet-filters order-of-execution


    【解决方案1】:
    1. 使 servlet 过滤器实现 spring Ordered 接口。
    2. 在配置类中手动声明 servlet 过滤器 bean。
        import org.springframework.core.Ordered;
        
        public class MyFilter implements Filter, Ordered {
    
            @Override
            public void init(FilterConfig filterConfig) {
                // do something
            }
    
            @Override
            public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
                // do something
            }
    
            @Override
            public void destroy() {
                // do something
            }
    
            @Override
            public int getOrder() {
                return -100;
            }
        }
    
    
        import org.springframework.context.annotation.ComponentScan;
        import org.springframework.context.annotation.Configuration;
    
        @Configuration
        @ComponentScan
        public class MyAutoConfiguration {
    
            @Bean
            public MyFilter myFilter() {
                return new MyFilter();
            }
        }
    

    【讨论】:

      【解决方案2】:

      您确实不能使用@WebFilter 注解定义过滤器执行顺序。但是,为了最大限度地减少 web.xml 的使用,只需使用 filterName 注释所有过滤器就足够了,这样您就不需要 <filter> 定义,而只需按所需顺序定义 <filter-mapping> 即可。

      例如,

      @WebFilter(filterName="filter1")
      public class Filter1 implements Filter {}
      
      @WebFilter(filterName="filter2")
      public class Filter2 implements Filter {}
      

      web.xml 中就是这样:

      <filter-mapping>
          <filter-name>filter1</filter-name>
          <url-pattern>/url1/*</url-pattern>
      </filter-mapping>
      <filter-mapping>
          <filter-name>filter2</filter-name>
          <url-pattern>/url2/*</url-pattern>
      </filter-mapping>
      

      如果您想将 URL 模式保留在 @WebFilter 中,那么您可以这样做,

      @WebFilter(filterName="filter1", urlPatterns="/url1/*")
      public class Filter1 implements Filter {}
      
      @WebFilter(filterName="filter2", urlPatterns="/url2/*")
      public class Filter2 implements Filter {}
      

      但您仍应将&lt;url-pattern&gt; 保留在web.xml 中,因为根据 XSD,它是必需的,尽管它可以为空:

      <filter-mapping>
          <filter-name>filter1</filter-name>
          <url-pattern />
      </filter-mapping>
      <filter-mapping>
          <filter-name>filter2</filter-name>
          <url-pattern />
      </filter-mapping>
      

      无论采用何种方法,这一切都将在 Tomcat 中失败,直到版本 7.0.28,因为它会在没有 &lt;filter&gt; 的情况下出现 &lt;filter-mapping&gt; 时窒息。另见Using Tomcat, @WebFilter doesn't work with <filter-mapping> inside web.xml

      【讨论】:

      • 他们可以引入嵌套 @WebFilterMapping 注释的 order 属性。我想知道是否为了简单起见没有这样做
      • @Bozho:那还不够具体。如果您的 web 应用程序附带包含过滤器的 3rd 方库怎么办?很难事先说出它的顺序。
      • @BalusC:您的示例中出了点问题:url-pattern 以过滤器名称关闭。
      • @AndrewBourgeois:已修复。是复制粘贴错误。太糟糕了,Markdown 编辑器没有像 Eclipse 那样的内置 XML 验证;)
      • 在 JBoss EAP 6.1 上使用 &lt;url-pattern /&gt; 不起作用 - 它会覆盖 @WebFilter 值并阻止过滤器运行。
      【解决方案3】:

      Servlet 3.0 规范似乎没有提供关于容器应如何排序已通过注释声明的过滤器的提示。不过,如何通过 web.xml 文件中的声明对过滤器进行排序是很清楚的。

      注意安全。使用具有相互依赖性的 web.xml 文件顺序过滤器。尝试使您的过滤器的所有顺序独立,以尽量减少使用 web.xml 文件的需要。

      【讨论】:

      • 我的项目中有许多 Servlet 过滤器,其中只有一个特定的过滤器必须首先调用,其他过滤器的顺序无关紧要。我是否必须污染 web.xml 中的所有过滤器?或者有什么捷径?
      猜你喜欢
      • 2013-06-09
      • 2014-04-22
      • 1970-01-01
      • 2015-09-22
      • 2023-04-03
      • 2014-01-05
      • 2019-05-23
      • 2011-12-30
      相关资源
      最近更新 更多