这些标记指示所有未处理的异常会转到/errorhandler这个URL去,在这里就是映射到ErrorHandlerServlet类。这是一个专门的servlet用来作为网页组件与异常处理框架之间的桥梁。当来自网页应用的未处理异常到达servlet容器中,一组包含异常信息的参数会被增加到HttpServletRequest实例并且传递给ErrorHandlerServlet类的service方法。下面的片断例示了service方法:
...
private static final String CONST_EXCEPTION = "javax.servlet.error.exception";
...
protected void service(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
throws ServletException, IOException
{
Throwable exception = (Throwable)httpServletRequest.getAttribute(CONST_EXCEPTION);
ExceptionHandler handler = ConfigHelper.getWARExceptionHandler();
handler.handle(Thread.currentThread(), exception);
String responsePage = (String)ConfigHelper.getRequestContextFactory().
getRequestContext().
getAttribute(ExceptionConstants.CONST_RESPONSEPAGE);
if(responsePage == null) {
responsePage = "/error.jsp";
}
httpServletResponse.setStatus(HttpServletResponse.SC_OK);
RequestDispatcher dispatcher = httpServletRequest.getRequestDispatcher(responsePage);
try {
dispatcher.include(httpServletRequest, httpServletResponse);
} catch (Exception e) {
log.error("Failed to dispatch error to responsePage " + responsePage, e);
}
}
在service方法中,首先来自HttpServletRequest实例的实际异常会通过javax.servlet.error.exception键获取;然后获取异常处理器实例:最后异常处理器处理异常并将HttpServletRequest实例转向到rampart.servlet.exception.responsepage键定义的页面。
DefaultWARExceptionHandler类查找异常信息所对应的国际化信息并重定向输出到/error.jsp。然后这个页面显示信息给用户,包括当前的请求ID。更复杂的机制可以通过简单地扩展或代替这个处理器来实现。
小结
通常异常处理并没有被迅速地处理掉,因而复杂的调试和错误信息在许多时候破坏了整个用户感受。因此在系统开发启动之前准备好异常处理的策略和框架是重要的。在开发完成后再进行修补也是可行的,但代价要昂贵的多。
这篇文章给了你定义异常策略的起点,并且介绍给你一个简单但可扩展的非强制异常层次。我们已经通览了一个示例J2EE架构的业务和客户端层,并且告诉你如何安装顶层的异常处理器来提供一个防卫的底线。框架代码也告诉你一种通过附加给异常和日志入口的唯一请求ID的方式来确定基于每用户请求的确切错误。
你可以下载这个框架,尝试一下,并根据你的需求来更改并在你控制下获取异常。
