Статьи

HOW-TO: пользовательские страницы ошибок в Tomcat с Spring MVC

Страницы ошибок Tomcat по умолчанию выглядят страшно. Кроме того, они могут предоставлять ценную информацию, включая версию сервера и трассировку стека исключений. Спецификация сервлета позволяет настроить исключительное поведение через web.xml. Можно настроить либо реакцию на конкретное исключение Java, либо на выбранный код (ы) Http-ответа.

Элемент error-page указывает соответствие между кодом ошибки или типом исключения и путем к ресурсу в веб-приложении:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
<web-app>
   
 <!-- Prior to Servlet 3.0 define either an error-code or an exception-type but not both -->
 <error-page>
  <!-- Define error page to react on Java exception -->
  <exception-type>java.lang.Throwable</exception-type>
  <!-- The location of the resource to display in response to the error will point to the Spring MVC handler method -->
  <location>/error</location>
 </error-page>
  
 <error-page>
  <error-code>404</error-code>
  <location>/error</location>
 </error-page>
   
 <!-- With Servlet 3.0 and above general error page is possible -->
 <error-page>
  <location>/error</location>
 </error-page>
  
</web-app>

Определив пользовательские страницы ошибок в нашем файле web.xml, нам нужно добавить Spring MVC @Controller . customError обработчика customError переносит информацию, которую мы получаем из запроса, и возвращает ее в представление.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Controller
class CustomErrorController {
 
 @RequestMapping("error")
 public String customError(HttpServletRequest request, HttpServletResponse response, Model model) {
  // retrieve some useful information from the request
  Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
  Throwable throwable = (Throwable) request.getAttribute("javax.servlet.error.exception");
  // String servletName = (String) request.getAttribute("javax.servlet.error.servlet_name");
  String exceptionMessage = getExceptionMessage(throwable, statusCode);
 
  String requestUri = (String) request.getAttribute("javax.servlet.error.request_uri");
  if (requestUri == null) {
   requestUri = "Unknown";
  }
 
  String message = MessageFormat.format("{0} returned for {1} with message {3}",
   statusCode, requestUri, exceptionMessage
  );
 
  model.addAttribute("errorMessage", message); 
  return "customError";
 }
 
 private String getExceptionMessage(Throwable throwable, Integer statusCode) {
  if (throwable != null) {
   return Throwables.getRootCause(throwable).getMessage();
  }
  HttpStatus httpStatus = HttpStatus.valueOf(statusCode);
  return httpStatus.getReasonPhrase();
 }
}

Полученное сообщение может выглядеть следующим образом: 404 returned for /sandbox/bad with message Not Found .

Чтобы увидеть код в действии, просмотрите исходный код Spring MVC Quickstart Archretype или, что еще лучше, создайте с ним новый проект.