使用Tomcat7。相关web.xml部分如下所示:
web.xml
<filter> <filter-name>Filter</filter-name> <filter-class>my.company.Filter</filter-class> </filter> <filter-mapping> <filter-name>Filter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <error-page> <error-code>404</error-code> <location>404.jsp</location> </error-page>
的代码Filter如下所示(简化):
Filter
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { System.out.println("Filter start"); chain.doFilter(request, response); System.out.println("Filter finish"); }
404.jsp看起来像这样(非常简化):
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <% System.out.println("404 here"); %>
打开不存在的页面(如/foobar)的stdout输出是这样的:
/foobar
Filter start Filter finish 404 here
因此,换句话说,当Tomcat弄清楚不存在的页面不存在时,Filter运行正常。但是在渲染404页面时,它并没有立即包装在中Filter。否则404页面会很好Filter地呈现,并且正确地应用于了所有其他(未转发的)JSP。
如果我直接访问404.jsp,Filter则正确应用了。只有在我访问某些缺少的JSP的情况下,Filter才会首先调用(请参见上面的日志),然后才对404.jsp进行评估- 但不会被包裹Filter。
如何使过滤器也包装404.jsp?
您需要阅读servlet规范的6.2.5节。
您的映射相当于
<filter-mapping> <filter-name>Filter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> </filter-mapping>
您至少要:
<filter-mapping> <filter-name>Filter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>ERROR</dispatcher> </filter-mapping>
因此,过滤器映射适用于错误页面以及常规请求。
其他调度程序设置可用。