Как получить неперехваченные исключения в веб-приложении сервлета Java

Есть ли стандартный способ поймать необработанные исключения, которые происходят внутри контейнера сервлетов Java, такого как tomcat или Jetty? Мы запускаем много сервлетов, которые поступают из библиотек, поэтому мы не можем легко поместить наш код try/catch. Также было бы неплохо как можно более общим образом перехватывать и регистрировать все неперехваченные исключения в нашем веб-приложении (которое работает в Jetty) в нашем средстве отслеживания ошибок через предоставленный API.

Пожалуйста, не нужно регистрировать только исключения, если перенаправление на пользовательскую страницу ошибки мне не поможет. Мы делаем все через GWT-RPC, чтобы пользователь никогда не увидел страницу с ошибкой.


person benstpierre    schedule 14.09.2011    source источник


Ответы (3)


Я думаю, что пользовательский фильтр действительно работает лучше всего.

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    try {
        chain.doFilter(request, response);
    } catch (Throwable e) {
        doCustomErrorLogging(e);
        if (e instanceof IOException) {
            throw (IOException) e;
        } else if (e instanceof ServletException) {
            throw (ServletException) e;
        } else if (e instanceof RuntimeException) {
            throw (RuntimeException) e;
        } else {
            //This should never be hit
            throw new RuntimeException("Unexpected Exception", e);
        }
    }
}
person benstpierre    schedule 14.09.2011
comment
Сообщение об использовании error-page - правильный способ сделать это в среде сервлета. - person nilskp; 25.04.2013
comment
На самом деле приведенное выше решение javax.servlet.Filter прекрасно работает в среде сервлетов. И мне нравится тот факт, что нам не нужно редактировать для этого файл web.xml. - person David; 03.04.2014
comment
этот пример вызовет побочный эффект перехвата ошибок (подкласса, отличного от исключений, от throwable и преобразования их в исключения). Поскольку ошибки — это внутренние проблемы, связанные с самой JVM (например, OutOfMemoryError или ThreadDeath). Поскольку сама JVM должна обрабатывать ошибки, это плохая практика — перехватывать метательные объекты и преобразовывать их в исключения, которые не будут обрабатываться JVM должным образом. ( stackoverflow.com /вопросы/6083248/) - person Andrew Norman; 28.01.2016

В web.xml (дескриптор развертывания) вы можете использовать элемент <error-page>, чтобы указать страницы ошибок по типу исключения или код статуса ответа HTTP. Например:

<error-page>
    <error-code>404</error-code>
    <location>/error/404.html</location>
</error-page>
<error-page>
    <exception-type>com.example.PebkacException</exception-type>
    <location>/error/UserError.html</location>
</error-page>

Описание, ориентированное на NetBeans, см. на Настройка веб-приложений: сопоставление ошибок с экранами ошибок (Учебное пособие по Java EE 6) (или см. версию учебного пособия по Java EE 5) ).

person Matt Ball    schedule 14.09.2011
comment
Стоит отметить, что код сервлета обработки ошибок может извлекать исключение из объекта request в атрибуте javax.servlet.error.exception. Например: request.getAttribute("javax.servlet.error.exception") - person nilskp; 25.04.2013

Не уверен на 100 %, будет ли это работать с контейнером сервлетов или насколько далеко вверх по течению должен идти этот вызов, но вы можете вызвать метод static setDefaultUncaughtExceptionHandler для Thread, чтобы установить обработчик, который будет обрабатывать все неперехваченные исключения.

person Matt Crinklaw-Vogt    schedule 14.09.2011