Подтвердить что ты не робот

Servlet Servlet: как получить исключение

У меня есть сервлет ошибок, настроенный в моем web.xml:

<error-page>
    <exception-type>java.lang.Exception</exception-type>
    <location>/ExceptionHandler</location>
</error-page>

верно?

В моем (общем) сервлете:

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.

4b9b3361

Ответ 1

Если исключение, пойманное сервером servletcontainer, является ServletException, и объявляется <error-page> для исключения исключения, отличного от ServletException, тогда его причина будет фактически распакована и сохранена как "javax.servlet.error.exception". Таким образом, у вас в основном уже есть переменная throwable, и вам не нужно называть ее getCause().

См. также 5-й параграф главы 9.9.2 спецификации Servlet 2.5:

Если объявление error-page, содержащее exception-type, подходит для использования class-hierarchy, а исключение - ServletException или подкласс, , контейнер извлекает завернутое исключение, как определено в ServletException.getRootCause. Выполняется второй проход по ошибке объявления страницы, снова попытка совпадения с объявлениями страницы ошибки, но вместо этого используется обернутое исключение.

Кстати, лучше использовать константу RequestDispatcher#ERROR_EXCEPTION вместо жесткого кодирования.

Throwable throwable = (Throwable) request.getAttribute(RequestDispatcher.ERROR_EXCEPTION);

Ответ 2

Редакцией.

Хорошо, это может быть неправильно, у меня нет личного опыта работы с сервлетами обработки ошибок: вместо getCause() добавить instanceof проверьте ServletException, если он пройдет, бросьте Throwable в ServletException и используйте getRootCause(). (У BalusC, похоже, есть лучшее решение для новых версий API Servlet)

См. Исключения без основной причины для углубленного обсуждения.

В новых версиях API Servlet нет этой проблемы, но , если вы используете старую версию (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;
    }
}