«1. Введение

В этом руководстве мы собираемся обрабатывать исключения в приложении Jakarta EE Servlet, чтобы обеспечить корректный и ожидаемый результат при возникновении ошибки.

2. Исключения сервлета Jakarta EE

Во-первых, мы определим сервлет, используя аннотации API (см. Servlets Intro для более подробной информации) с процессором GET по умолчанию, который будет генерировать исключение:

@WebServlet(urlPatterns = "/randomError")
public class RandomErrorServlet extends HttpServlet {

    @Override
    protected void doGet(
      HttpServletRequest req, 
      HttpServletResponse resp) {
        throw new IllegalStateException("Random error");
    }
}

3. Обработка ошибок по умолчанию

Давайте теперь просто развернем приложение в нашем контейнере сервлетов (предположим, что приложение работает под http://localhost:8080/javax-servlets).

Когда мы получим доступ к адресу http://localhost:8080/javax-servlets/randomError, мы увидим обработку ошибок сервлета по умолчанию:

Обработка ошибок по умолчанию обеспечивается контейнером сервлета и может быть настроена на уровне контейнера или приложения.

4. Пользовательская обработка ошибок

Мы можем определить пользовательскую обработку ошибок, используя файловый дескриптор web.xml, в котором мы можем определить следующие типы политик:

    Обработка ошибок кода состояния — это позволяет нам отображать Коды ошибок HTTP (клиент и сервер) на статическую HTML-страницу ошибок или сервлет обработки ошибок. Обработка ошибок типов исключений — это позволяет нам отображать типы исключений на статические HTML-страницы ошибок или сервлет обработки ошибок

4.1. Обработка ошибок кода состояния с помощью HTML-страницы

Мы можем настроить собственную политику обработки ошибок для ошибок HTTP 404 в файле web.xml:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns="http://java.sun.com/xml/ns/javaee"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1">

    <error-page>
        <error-code>404</error-code>
        <location>/error-404.html</location> <!-- /src/main/webapp/error-404.html-->
    </error-page>

</web-app>

Теперь откройте http://localhost:8080/javax-servlets /invalid.html из браузера — чтобы получить статическую HTML-страницу с ошибкой.

4.2. Обработка ошибок типа исключения с помощью сервлета

Мы можем настроить собственную политику обработки ошибок для java.lang.Exception в web.xml:

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
  xmlns="http://java.sun.com/xml/ns/javaee"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1">
    <error-page> 
        <exception-type>java.lang.Exception</exception-type> 
        <location>/errorHandler</location> 
    </error-page>
</web-app>

В ErrorHandlerServlet мы можем получить доступ к сведениям об ошибке, используя предоставленные атрибуты ошибки в запросе:

@WebServlet(urlPatterns = "/errorHandler")
public class ErrorHandlerServlet extends HttpServlet {

    @Override
    protected void doGet(
      HttpServletRequest req, 
      HttpServletResponse resp) throws IOException {
 
        resp.setContentType("text/html; charset=utf-8");
        try (PrintWriter writer = resp.getWriter()) {
            writer.write("<html><head><title>Error description</title></head><body>");
            writer.write("<h2>Error description</h2>");
            writer.write("<ul>");
            Arrays.asList(
              ERROR_STATUS_CODE, 
              ERROR_EXCEPTION_TYPE, 
              ERROR_MESSAGE)
              .forEach(e ->
                writer.write("<li>" + e + ":" + req.getAttribute(e) + " </li>")
            );
            writer.write("</ul>");
            writer.write("</html></body>");
        }
    }
}

Теперь мы можем получить доступ к http://localhost:8080/javax-servlets/randomError, чтобы увидеть работу пользовательского сервлета ошибок.

Примечание. Наш тип исключения, определенный в файле web.xml, слишком широк, и нам следует указать все исключения, которые мы хотим обрабатывать, более подробно.

Мы также можем использовать предоставленный контейнером регистратор сервлетов в нашем компоненте ErrorHandlerServlet для регистрации дополнительных сведений:

Exception exception = (Exception) req.getAttribute(ERROR_EXCEPTION);
if (IllegalArgumentException.class.isInstance(exception)) {
    getServletContext()
      .log("Error on an application argument", exception);
}

Стоит знать, что выходит за рамки механизмов журналирования, предоставляемых сервлетом, см. руководство по slf4j для получения более подробной информации.

5. Заключение

В этой краткой статье мы рассмотрели обработку ошибок по умолчанию и указали пользовательскую обработку ошибок в приложении сервлета без добавления внешних компонентов или библиотек.

Как всегда, вы можете найти исходный код в репозитории учебных пособий по сервлетам.