呈现时的JSP / spring-mvc异常-如何获得自定义错误页面并记录异常



如果服务或控制器中发生异常,则由spring的HandlerExceptionResolvers处理。但是,如果.jsp处理中有异常(例如- PropertyNotFoundException,即使使用JSTL也会发生),那么spring不会通过其异常处理机制传递此异常。此外,它不被认为是错误500,因此不考虑<error-page>配置

相反,异常被传播到servlet容器。这很好,但我实际上不能得到我想要的行为:
  • 显示(500)错误页面
  • 记录异常

我的当前设置:

  • 500.jsp有isErrorPage=true
  • 所有jsp都包含一个公共文件,该文件包含<%@ page errorPage="500.jsp" %>

发生的是-异常没有记录在任何地方。错误页面没有显示。相反,所请求的页面只显示一半。如果我增加缓冲区大小(足以到达有问题的代码段),则只显示错误页面。(同样,没有日志记录)

那么,我如何实现我想要的呢?不改变缓冲区大小,不使用<c:catch>,在错误页面中不使用ex.printStackTrace())

添加到web.xml:

<servlet>
  <servlet-name>ErrorServlet</servlet-name>
  <servlet-class>package.of.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>ErrorServlet</servlet-name>
  <url-pattern>/WEB-INF/servlets/error</url-pattern>
</servlet-mapping>
<error-page>
  <exception-type>java.lang.Throwable</exception-type>
  <location>/WEB-INF/servlets/error</location>
</error-page>

在ErrorServlet中实现doService方法,因为servlet容器将在那里转发任何当前操作(GET, POST等)。

添加辅助方法

    public static < T extends Throwable > T getExceptionFromRequest (
            final Class< T > exception_class,
            final HttpServletRequest request                
        )
    {
        final T ret_val =
            exception_class.cast(
                request.getAttribute( SERVLET_EXCEPTION_ATTR )
            );
        if ( ret_val != null )
        {
            return ret_val;
        }
        return
            exception_class.cast(
                request.getAttribute( JSP_EXCEPTION_ATTR )
            );
    }

和这两个常数:

    public final static String SERVLET_EXCEPTION_ATTR =
        "javax.servlet.error.exception";
    public final static String JSP_EXCEPTION_ATTR =
        "javax.servlet.jsp.jspException";

你可以使用一个HandlerInterceptor,有一个空的preHandle()postHandle(),但这迎合了afterComplete()的例外吗?

似乎有两个问题:

    您可以直接在JSP中设置缓冲区大小,以避免半渲染;因为你已经设置了isErrorPage,这将遵循你当前的设计
  1. 您可以从500页记录错误,如下例

最新更新