如果我们在 WAR 自己的
web.xml
中定义 webapp 特定的 servlet 过滤器,那么过滤器的执行顺序将与它们在 web.xml
中定义的顺序相同。
但是,如果我们使用
@WebFilter
注解来定义那些过滤器,过滤器的执行顺序是什么,我们如何确定执行顺序?
@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 {}
但是您仍然应该保留
<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>
无论采用何种方法,在 Tomcat 7.0.28 版之前,这一切都将失败,因为它会在没有
<filter-mapping>
的情况下出现 <filter>
时窒息。另请参阅使用 Tomcat,@WebFilter 不适用于 web.xml 中的Servlet 3.0 规范似乎没有提供有关容器应如何排序已通过注释声明的过滤器的提示。不过,很清楚如何通过 web.xml 文件中的声明来订购过滤器。
注意安全。使用具有相互依赖性的 web.xml 文件顺序过滤器。尝试让您的过滤器完全独立于顺序,以尽量减少使用 web.xml 文件的需要。
如果您的项目中存在 Spring,您可以在类上使用
org.springframework.core.annotation.Order
注释。 F.e. @Order(0)
, @Order(1)
等
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();
}
}