如何使用WAR中的注释定义servlet过滤器的执行顺序

时间:2011-07-03 03:38:00

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

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

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

4 个答案:

答案 0 :(得分:173)

您确实无法使用@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中,那么您可以这样做,

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

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

但您仍应将<url-pattern>保留在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>

无论采用何种方法,在版本7.0.28之前,这一切都将在Tomcat中失败,因为它会因<filter-mapping>没有<filter>而出现问题。另请参阅Using Tomcat, @WebFilter doesn't work with <filter-mapping> inside web.xml

答案 1 :(得分:11)

Servlet 3.0规范似乎没有提供容器如何订购通过注释声明的过滤器的提示。很明显,如何通过web.xml文件中的声明来命令过滤器。

安全。使用具有相互依赖性的web.xml文件顺序筛选器。尝试使您的过滤器所有顺序独立,以最大限度地减少使用web.xml文件的需要。

答案 2 :(得分:0)

@WebFilter没有元素来定义过滤器执行的顺序。如果需要它,则应选择web.xml。

答案 3 :(得分:0)

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