java 错误处理程序 Servlet:如何获取异常原因
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4207586/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Error Handler Servlet: how to get exception cause
提问by bluefoot
I have an error servlet configured in my web.xml:
我在 web.xml 中配置了一个错误 servlet:
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/ExceptionHandler</location>
</error-page>
right?
对?
In my (generically) servlet:
在我的(一般)servlet 中:
doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
...
...
} catch (Exception e) {
throw new ServletException("some mesage", e);
}
}
so, "e" will be the root cause in this case.
因此,在这种情况下,“e”将是根本原因。
In my ExceptionHandler class, I have:
在我的 ExceptionHandler 类中,我有:
doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Throwable throwable = (Throwable) request.getAttribute("javax.servlet.error.exception");
throwable.getCause() //NULL
}
this is the problem. throwable.getCause() is null.
这就是问题。throwable.getCause() 为空。
回答by BalusC
If the exception caught by the servletcontainer is a ServletException
and the <error-page>
is declared to catch an exception otherthan ServletException
, then its cause will actually be unwrapped and stored as "javax.servlet.error.exception"
. So you basically already have it as throwable
variable and you don't need to call getCause()
on it.
如果由servletcontainer捕捉到的异常是ServletException
和<error-page>
声明捕捉异常其他比ServletException
,那么它的原因实际上是打开并作为存储"javax.servlet.error.exception"
。所以你基本上已经把它作为throwable
变量了,你不需要调用getCause()
它。
See also 5th paragraph of chapter 9.9.2 of Servlet 2.5 specification:
另请参阅Servlet 2.5 规范第 9.9.2 章的第 5 段:
If no
error-page
declaration containing anexception-type
fits using the class-hierarchy match, and the exception thrown is aServletException
or subclass thereof, the container extracts the wrapped exception, as defined by theServletException.getRootCause
method. A second pass is made over the error page declarations, again attempting the match against the error page declarations, but using the wrapped exception instead.
如果使用类层次结构匹配没有
error-page
包含exception-type
fit 的声明,并且抛出的异常是 aServletException
或其子类,则容器提取包装的异常,如ServletException.getRootCause
方法所定义 。对错误页面声明进行第二次传递,再次尝试与错误页面声明进行匹配,但使用包装的异常代替。
By the way, it's better to use the RequestDispatcher#ERROR_EXCEPTION
constant instead of hardcoding it.
顺便说一句,最好使用RequestDispatcher#ERROR_EXCEPTION
常量而不是对其进行硬编码。
Throwable throwable = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);
回答by Neeme Praks
EDITED.
已编辑。
Ok, this might be wrong, I do not have personal experience with error handling servlets: Instead of getCause(), add an instanceof
check for ServletException, if it passes, cast your Throwable to ServletExceptionand use getRootCause().(BalusC seems to have a better solution, for newer Servlet API versions)
好吧,这可能是错误的,我没有处理 servlet 错误的个人经验:添加对ServletException的检查,而不是getCause(),如果通过,将 Throwable 转换为ServletException并使用getRootCause()。instanceof
(对于较新的 Servlet API 版本,BalusC 似乎有更好的解决方案)
See Exceptions Without Root Causefor in-depth discussion.
有关深入讨论,请参阅无根本原因的异常。
Newer Servlet API versions do not have this issue, but if you are using some old version (2.4or older)you should also update your ServletException throwing code:
较新的 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;
}
}