如何使用注解在WAR中定义Servlet过滤器执行顺序

190
如果我们在WAR文件的web.xml中定义Web应用程序特定的Servlet过滤器,那么这些过滤器的执行顺序将与它们在web.xml中定义的顺序相同。
但是,如果我们使用@WebFilter注释来定义这些过滤器,那么过滤器的执行顺序是什么,如何确定执行顺序呢?
4个回答

206
您确实可以不使用@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>

如果您想保留 @WebFilter 中的URL模式,则可以像这样操作:

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

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

但是您仍应该在web.xml中保留<url-pattern>,因为根据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及之前的版本中失败,因为它无法处理没有 <filter><filter-mapping>。详见在Tomcat中使用@WebFilter,带有<filter-mapping>的web.xml无效


7
他们本可以在嵌套的@WebFilterMapping注解中引入一个“order”属性。我想知道他们是否没有这样做是为了简单起见。 - Bozho
13
@Bozho: 如果你的Web应用程序与包含筛选器的第三方库一起发布,那就不够具体了。很难事先确定它的顺序。 - BalusC
3
已修复。这是一次复制粘贴错误。可惜的是,Markdown编辑器没有像Eclipse中那样内置XML验证。 - BalusC
1
@Craig:你显然从未尝试过他的答案。他的答案根本不起作用<absolute-ordering>有完全不同的目的。我完全不明白为什么它现在有12个投票。 - BalusC
8
在JBoss EAP 6.1中使用<url-pattern />无法正常工作-它会覆盖@WebFilter的值并阻止过滤器运行。 - seanf
显示剩余9条评论

13

Servlet 3.0规范似乎没有提供关于如何通过注解声明顺序的过滤器的提示。但是,在web.xml文件中声明的过滤器顺序是清楚的。

为了确保过滤器之间的依赖性,使用web.xml文件来排序过滤器会更加安全。 尽量使您的过滤器独立排序,以最小化使用web.xml文件的必要性。


4
我有许多Servlet过滤器在我的项目中,其中只有一个特定的过滤器必须首先被调用,其他过滤器的顺序并不重要。我是否需要在web.xml中定义所有过滤器?还是有任何捷径可用?答:您在项目中有许多Servlet过滤器,在其中只有一个特定的过滤器需要首先被调用,而其他过滤器的顺序则不重要。您是否需要在web.xml文件中定义所有过滤器?或者有没有其他捷径可用? - siva636

0
如果您的项目中存在Spring,您可以在类上使用org.springframework.core.annotation.Order注释。例如:@Order(0)@Order(1)等。

-3
  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();
        }
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接