如果服务或 Controller 发生异常,由spring的HandlerExceptionResolvers处理。但是,如果在 .jsp 处理中存在异常(例如 - PropertyNotFoundException
,即使使用 JSTL 也会发生),那么 spring 不会通过其异常处理机制传递它。此外,它不被视为错误 500,因此 <error-page>
不考虑配置
相反,异常被传播到 servlet 容器。这很好,但我实际上无法获得我想要的行为:
- 显示 (500) 错误页面
- 记录异常
我当前的设置:
- 500.jsp 有
isErrorPage=true
- 所有的 jsps 都包含一个公共(public)文件,其中有
<%@ 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";
这在 Tomcat 中一直对我有用。
关于java - 渲染上的 jsp/spring-mvc 异常 - 如何获取自定义错误页面并记录异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7492050/