【问题标题】:jsp / spring-mvc exception on render - how to get custom error page and log the exceptionjsp / spring-mvc 渲染异常 - 如何获取自定义错误页面并记录异常
【发布时间】:2011-11-21 11:11:03
【问题描述】:

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

相反,异常会传播到 servlet 容器。这很好,但我实际上无法获得我想要的行为:

  • 显示 (500) 错误页面
  • 记录异常

我目前的设置:

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

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

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

【问题讨论】:

  • 你使用的是什么 ViewResolver?
  • InternalResourceViewResolver 与 JstlView。春天 3.1.0.SNAPSHOT。雄猫 7
  • 博卓,你有没有很好地解决过这个问题?

标签: java jsp tomcat servlets spring-mvc


【解决方案1】:

将此添加到 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";

这一直在 Tomcat 中为我工作。

【讨论】:

  • 嗯..明天我会验证的。但即使它有效,我也不太喜欢它——它充其量只是一种解决方法。我在某处“感觉到”了一个 tomcat 错误。
  • @Bozho。 javax.servlet.jsp.jspException 是一个 Tomcat hack,可能甚至不再需要它,但 javax.servlet.error.exception 直接来自 Servlet API 2.3 (java.sun.com/developer/technicalArticles/Servlets/servletapi2.3)
【解决方案2】:

你能使用一个HandlerInterceptor,它有一个空的preHandle()postHandle(),但它满足afterComplete() 中的异常吗?

【讨论】:

  • 确实可以做日志部分,但是异常会传播到servlet容器,所以缓冲区问题仍然存在
  • 使用 servlet 过滤器将响应包装为仅内存输出流。如果出现错误则丢弃内容并输出您的 http 500 和自定义消息。
  • 嗯,是的,我知道我可以添加一个过滤器,但这也是一种解决方法。我向tomcat报告了一个问题,让我们看看他们的解释/建议是什么
【解决方案3】:

好像有两个问题:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    • 2014-04-06
    • 2019-01-02
    • 2015-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多