10

我有两个错误页面;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除外)

有没有更好的方法来指定特定的异常处理程序?我正在使用弹簧 3.0。

4

2 回答 2

11

这不是 Tomcat 特有的。这是特定于 Servlet API 的。Servlet API 规范 2.5的第 9.9.2 章规定了如何确定错误页面。这是相关性的摘录:

SRV.9.9.2 错误页面

如果没有error-page包含exception-type使用类层次结构匹配的声明,并且抛出的异常是一个ServletException或其子类,则容器提取包装的异常,如方法所定义的那样ServletException.getRootCause。对错误页面声明进行第二次传递,再次尝试匹配错误页面声明,但使用包装的异常。

因此,您SpecificExceptionA可能被包裹在 a 中ServletException,因此java.lang.Throwable是第一次通过时最接近的匹配。当您删除此条目时,将使用包装的异常进行第二次传递,从而SpecificExceptionA获得匹配项。

定义一般 HTTP 500 错误页面的正确方法是将其映射到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监听 anurl-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;
        }
    }
}

它只需要扩展 fromRuntimeException才能使其工作。

于 2011-03-14T13:51:50.547 回答
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>
于 2011-03-14T14:08:37.997 回答