error handling程序Servlet:如何获取exception原因
我在web.xml中配置了一个错误的servlet:
java.lang.Exception /ExceptionHandler
对?
在我的(通用)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。
如果servletcontainer捕获的exception是ServletException
并且声明
捕获除ServletException
之外的exception,那么它的原因实际上将被解包并存储为"javax.servlet.error.exception"
。 所以你基本上已经把它作为throwable
变量,你不需要在它上面调用getCause()
。
另请参见Servlet 2.5规范第9.9.2节的第5段:
如果没有包含
exception-type
error-page
声明适合使用类层次结构匹配,并且抛出的exception是ServletException
或其子类, 则容器将提取由ServletException.getRootCause
方法定义的包装exception 。 对错误页面声明进行第二次传递,再次尝试匹配错误页面声明,但使用包装的exception。
顺便说一下,最好使用RequestDispatcher#ERROR_EXCEPTION
常量而不是硬编码。
Throwable throwable = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
编辑。
好吧,这可能是错的,我没有error handlingservlet的个人经验: 而不是getCause() ,为ServletException添加一个instanceof
检查,如果它通过,则将Throwable转换为ServletException并使用getRootCause() 。 (对于较新的Servlet API版本,BalusC似乎有更好的解决方案)
有关深入讨论,请参阅无根本例外情况 。
较新的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; } }