我有两个错误页面;1代表SpecificExceptionA,另一个代表Throwable。
<error-page> <exception-type>org.SpecificExceptionA</exception-type> <location>/WEB-INF/views/error/timedout.jsp</location> </error-page> <error-page> <exception-type>java.lang.Throwable</exception-type> <location>/WEB-INF/views/error/error.jsp</location> </error-page>
如果我在web.xml中都定义了这两者,则所有内容都将移至/error/error.jsp。
如果仅定义了特定的异常,它将转到正确的页面;但其他错误归于tomcat默认值(404除外)
有没有更好的方法来指定特定的异常处理程序?我正在使用Spring 3.0。
这并非特定于Tomcat。这特定于Servlet API。如何确定错误页面在Servlet API规范2.5的第9.9.2节中指定。这是相关的摘录:
SRV.9.9.2错误页面 如果没有使用类层次结构匹配的error-page包含声明的声明exception- type,并且抛出的异常是其ServletException子类或子类,则容器将提取该ServletException.getRootCause方法定义的包装后的异常。对错误页面声明进行第二遍处理,再次尝试与错误页面声明进行匹配,但改用包装的异常。
如果没有使用类层次结构匹配的error-page包含声明的声明exception- type,并且抛出的异常是其ServletException子类或子类,则容器将提取该ServletException.getRootCause方法定义的包装后的异常。对错误页面声明进行第二遍处理,再次尝试与错误页面声明进行匹配,但改用包装的异常。
error-page
exception- type
ServletException
ServletException.getRootCause
因此,您SpecificExceptionA很可能被包裹在ServletException,因此,java.lang.Throwable是第一遍最接近的比赛。当您删除该条目时,将通过包装的异常进行第二次传递,从而SpecificExceptionA获得匹配。
SpecificExceptionA
java.lang.Throwable
定义常规HTTP 500错误页面的正确方法是将其映射,error-code而不是exception-type:
error-code
exception-type
<error-page> <exception-type>org.SpecificExceptionA</exception-type> <location>/WEB-INF/views/error/timedout.jsp</location> </error-page> <error-page> <error-code>500</error-code> <location>/WEB-INF/views/error/error.jsp</location> </error-page>
如果由于某些不清楚的原因而无法使用此选项,则解决此问题的方法之一是创建一个Filter侦听url-patternof的a /*并基本上执行以下操作:
Filter
url-pattern
/*
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { try { chain.doFilter(request, response); } catch (ServletException e) { Throwable rootCause = e.getRootCause(); if (rootCause instanceof SpecificExceptionA) { throw (SpecificExceptionA) rootCause; } else { throw e; } } }
它仅需扩展RuntimeException即可使用。
RuntimeException