Я пишу веб-приложение с Spring 4.0.4 и Spring Boot 1.0.2 с использованием Tomcat в качестве встроенного веб-контейнера, и я хочу реализовать глобальную обработку исключений, которая перехватывает все исключения и записывает их в определенный путь. Мои простые требования:
- Я хочу глобально обрабатывать все исключения, которые еще не обрабатываются в другом месте (например, в обработчике исключений контроллера). Я хочу записать сообщение, и я хочу показать пользователю пользовательское сообщение об ошибке.
- Я не хочу, чтобы Spring или веб-контейнер регистрировали ошибки самостоятельно, потому что я хочу сделать это сам.
До сих пор мое решение выглядело следующим образом (упрощенный, без регистрации и переадресации на просмотр ошибок):
@Controller
@RequestMapping("/errors")
public class ErrorHandler implements EmbeddedServletContainerCustomizer
{
@Override
public void customize(final ConfigurableEmbeddedServletContainer factory)
{
factory.addErrorPages(new ErrorPage("/errors/unexpected"));
factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/errors/notfound"));
}
@RequestMapping("unexpected")
@ResponseBody
public String unexpectedError(final HttpServletRequest request)
{
return "Exception: " + request.getAttribute("javax.servlet.error.exception");
}
@RequestMapping("notfound")
@ResponseBody
public String notFound()
{
return "Error 404";
}
}
В результате исключения, создаваемые контроллерами, корректно обрабатываются методом unexpectedError
, а 404 кодов состояния обрабатываются методом notFound
. Пока все хорошо, но у меня есть следующие проблемы:
- Tomcat или Spring (не уверен, кто несет ответственность) все еще регистрирует сообщение об ошибке. Я не хочу этого, потому что я хочу сам регистрировать его (с дополнительной информацией), и я не хочу дублировать сообщения об ошибках в журнале. Как предотвратить эту регистрацию по умолчанию?
- То, как я обращаюсь к объекту исключения, кажется неправильным. Я извлекаю, если из атрибута request
javax.servlet.error.exception
. И это даже не исключенное исключение, это экземплярorg.springframework.web.util.NestedServletException
, и я должен погрузиться в это вложенное исключение, чтобы получить реальный. Я уверен, что есть более простой способ, но я не могу его найти.
Итак, как я могу решить эти проблемы? Или, может быть, способ, которым я реализовал этот глобальный обработчик исключений, совершенно неверен, и есть лучшая альтернатива?