jsp / spring-mvc 渲染异常 - 如何获取自定义错误页面并记录异常

发布于 2024-12-06 04:15:29 字数 710 浏览 1 评论 0原文

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

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

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

我当前的设置:

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

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

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

If an exception occurs in the service or controller, it is handled by spring's HandlerExceptionResolvers. However, if there is an exception in a .jsp processing (for example - PropertyNotFoundException, happens even with JSTL), then spring does not pass this through its exception handling mechanism. Further more, it is not considered an error 500, so the <error-page> configuration is not taken into account

Instead, the exception is propagated to the servlet container. Which is fine, but I can't actually get the behaviour I want:

  • show a (500) error page
  • log the exception

My current setup:

  • the 500.jsp has isErrorPage=true
  • all jsps include a common file, which has <%@ page errorPage="500.jsp" %>

What happens is - the exception is not recorded anywhere. And the error page is not shown. Instead, the requested page is shown half-rendered. If I increase the buffer size (enough to reach the problematic piece of code), only then the error page is shown. (again, no logging)

So, how do I achieve what I want? Without changing the buffer size, without using <c:catch>, and without ex.printStackTrace() in the error page)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

笑梦风尘 2024-12-13 04:15:29

将其添加到 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 中对我有用。

Add this to 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>

In the ErrorServlet implement doService method, because servlet container will forward there for any current action ( GET, POST, etc ).

Add this helper method

    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 )
            );
    }

And these 2 constants:

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

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

This has been working for me in Tomcat.

策马西风 2024-12-13 04:15:29

您可以使用 HandlerInterceptor 具有空的 preHandle()postHandle(),但可以满足以下条件的异常afterComplete()

Can you use a HandlerInterceptor that has an empty preHandle() and postHandle(), but that caters for Exceptions in afterComplete()?

无名指的心愿 2024-12-13 04:15:29

似乎有两个问题:

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

Seems like there are 2 issues:

  1. You can set the buffer size directly in your JSP to avoid the half-rendering; since you're already setting isErrorPage this would follow your current design
  2. You can log the error from the 500 page, as per this example
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文