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.
Ответы
Ответ 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;
}
}