我在web.xml中配置了一个错误的servlet:
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/ExceptionHandler</location>
</error-page>
正确?
在我的(通用)servlet中:
doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
...
...
} catch (Exception e) {
throw new ServletException("some mesage", e);
}
}
所以,“e”将是这种情况下的根本原因。
在我的ExceptionHandler类中,我有:
doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Throwable throwable = (Throwable) request.getAttribute("javax.servlet.error.exception");
throwable.getCause() //NULL
}
这是问题所在。 throwable.getCause()为null。
答案 0 :(得分:21)
如果servletcontainer捕获的异常是ServletException
并且<error-page>
被声明为捕获异常其他而不是ServletException
,那么其原因实际上是被打开并存储为"javax.servlet.error.exception"
。所以你基本上已经将它作为throwable
变量,并且你不需要在其上调用getCause()
。
另见Servlet 2.5 specification第9.9.2节的第5段:
如果包含
error-page
的{{1}}声明不适合使用 类层次结构匹配,抛出的异常是exception-type
或 其子类,容器提取包装的异常,由ServletException
方法。对错误进行第二次传递 页面声明,再次尝试匹配错误页面声明, 但改为使用包装的异常。
顺便说一下,最好使用RequestDispatcher#ERROR_EXCEPTION
常量而不是硬编码。
ServletException.getRootCause
答案 1 :(得分:-1)
编辑。
好吧,这可能是错误的,我没有处理servlet错误的个人经验:而不是getCause(),为ServletException添加instanceof
检查,如果通过,将你的Throwable转换为ServletException并使用getRootCause()。(对于较新的Servlet API版本,BalusC似乎有更好的解决方案)
请参阅Exceptions Without Root Cause进行深入讨论。
较新的Servlet API版本没有此问题,但如果您使用的是旧版本(2.4或更早版本),您还应该更新ServletException抛出代码:
doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
...
...
} catch (Exception e) {
ServletException se = new ServletException(e.getMessage(), e);
se.initCause(e);
throw se;
}
}