Если исключение возникает во время отображения запроса или генерируется из обработчика запроса (например, аннотированного @Controller), DispatcherServlet делегирует полномочия цепочке бинов HandlerExceptionResolver для распознавания исключения и обеспечения альтернативной обработки, которая обычно представляет собой сообщение об ошибке.

В следующей таблице перечислены доступные реализации HandlerExceptionResolver:

Таблица 2. Реализации HandlerExceptionResolver
HandlerExceptionResolver Описание

SimpleMappingExceptionResolver

Сопоставление между именами классов исключений и именами представлений ошибок. Используется для визуализации страниц ошибок в приложении браузера.

DefaultHandlerExceptionResolver

Распознает исключения, вызванные Spring MVC, и отображает их на коды состояния HTTP. См. также альтернативный ResponseEntityExceptionHandler.

ResponseStatusExceptionResolver

Распознает исключения с аннотацией @ResponseStatus и отображает их на коды статуса HTTP на основе значения в аннотации.

ExceptionHandlerExceptionResolver

Распознает исключения, вызывая метод, помеченный аннотацией @ExceptionHandler, в классе с аннотацией @Controller или аннотацией @ControllerAdvice.

Цепочка распознавателей

Вы можете сформировать цепочку распознавателей исключений, объявив несколько бинов HandlerExceptionResolver в конфигурации Spring и настроив их свойства order по мере необходимости. Чем выше свойство порядка, тем дальше располагается распознаватель исключений.

В контракте HandlerExceptionResolver задается, что он может возвращать:

  • ModelAndView, указывающий на представление ошибки.

  • Пустое ModelAndView, если исключение было обработано внутри распознавателя.

  • null, если исключение остается нераспознанным, для последующих попыток, предпринимаемых распознавателями, но, если исключение в конечном итоге остается, то оно допускается в контейнер сервлета.

Конфигурация MVC автоматически объявляет встроенные распознаватели для исключений Spring MVC по умолчанию, для аннотированных @ResponseStatus исключений и для поддержки методов, аннотированных @ExceptionHandler. Этот список можно изменить или заменить его.

Страница ошибки контейнера

Если исключение остается нераспознанным каким-либо HandlerExceptionResolver и, следовательно, продолжает распространяться, или если статус ответа установлен в состояние ошибки (то есть 4xx, 5xx), контейнеры сервлетов могут визуализировать страницу ошибки по умолчанию на HTML. Чтобы настроить страницу ошибок контейнера по умолчанию, можно объявить отображение страницы ошибок в web.xml. В следующем примере показано, как это сделать:

<error-page>
    <location>/error</location>
</error-page>

Учитывая предыдущий пример, если возникает исключение или ответ имеет состояние ошибки, контейнер сервлетов выполняет внутри контейнера отправку ERROR на сконфигурированный URL-адрес (например, /error). Затем все это обрабатывается DispatcherServlet, путем его возможного отображения на аннотацию @Controller, которая может быть реализована для возврата имени представления ошибки с моделью или для вывода ответа в формате JSON, как показано в следующем примере:

Java
@RestController
public class ErrorController {
    @RequestMapping(path = "/error")
    public Map<String, Object> handle(HttpServletRequest request) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("status", request.getAttribute("javax.servlet.error.status_code"));
        map.put("reason", request.getAttribute("javax.servlet.error.message"));
        return map;
    }
}
Kotlin
@RestController
class ErrorController {
    @RequestMapping(path = ["/error"])
    fun handle(request: HttpServletRequest): Map<String, Any> {
        val map = HashMap<String, Any>()
        map["status"] = request.getAttribute("javax.servlet.error.status_code")
        map["reason"] = request.getAttribute("javax.servlet.error.message")
        return map
    }
}
Servlet API не обеспечивает возможность создания отображений страниц ошибок на Java. Однако можно использовать как WebApplicationInitializer, так и простой web.xml.