我有两个错误页面; 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。
答案 0 :(得分:11)
这不是Tomcat特有的。这特定于Servlet API。如何确定错误页面在Servlet API specification 2.5的第9.9.2节中指定。以下是相关摘录:
SRV.9.9.2错误页面
如果包含
error-page
的{{1}}声明不适合使用 类层次结构匹配,抛出的异常是exception-type
或 其子类,容器提取包装的异常,如下所定义ServletException
方法。对错误进行第二次传递 页面声明,再次尝试匹配错误页面 声明,但改为使用包装的异常。
因此,您的ServletException.getRootCause
可能包含在ServletException
中,因此SpecificExceptionA
是第一次通过时最接近的匹配。当您删除此条目时,将使用包装的例外进行第二次传递,从而使您的java.lang.Throwable
获得匹配。
定义常规HTTP 500错误页面的正确方法是将其映射到SpecificExceptionA
而不是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-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;
}
}
}
延伸即可使其正常工作。
答案 1 :(得分:1)
我使用Springs SimpleMappingExceptionResolver类
结束了<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="org.*.*.ResponseTimeExceededException">
<!-- the name of the jsp to use for this exception -->
error/timedout
</prop>
</props>
</property>
<property name="defaultErrorView" value="error/error"/>
</bean>