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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 05:19:06  来源:igfitidea点击:

Error Handler Servlet: how to get exception cause

javaservletsexception-handling

提问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 ServletExceptionand 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 throwablevariable 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-pagedeclaration containing an exception-typefits using the class-hierarchy match, and the exception thrown is a ServletExceptionor subclass thereof, the container extracts the wrapped exception, as defined by the ServletException.getRootCausemethod. 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-typefit 的声明,并且抛出的异常是 aServletException或其子类,则容器提取包装的异常,如ServletException.getRootCause方法所定义 。对错误页面声明进行第二次传递,再次尝试与错误页面声明进行匹配,但使用包装的异常代替。

By the way, it's better to use the RequestDispatcher#ERROR_EXCEPTIONconstant 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 instanceofcheck 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;
    }
}