Como gravar um manipulador de erro global adequado com o Spring MVC / Spring Boot
Estou escrevendo um aplicativo Web com o Spring 4.0.4 e o Spring Boot 1.0.2 usando o Tomcat como contêiner da Web incorporado e quero implementar um tratamento de exceção global que intercepte todas as exceções e as registre de uma maneira específica. Meus requisitos simples são:
Eu quero manipular globalmente todas as exceções que ainda não foram processadas em outro lugar (em um manipulador de exceções do controlador, por exemplo). Desejo registrar a mensagem e exibir uma mensagem de erro personalizada para o usuário.Não quero que o Spring ou o contêiner da web registre erros sozinho, porque quero fazer isso sozinho.Até agora, minha solução se parece com esta (simplificada, sem registro e sem redirecionamento para uma exibição de erro):
@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";
}
}
O resultado é que as exceções lançadas nos controladores são tratadas corretamente pelounexpectedError
método e códigos de status 404 são manipulados pelonotFound
método. Até aí tudo bem, mas tenho os seguintes problemas:
javax.servlet.error.exception
. E essa nem é a exceção lançada, é uma instância deorg.springframework.web.util.NestedServletException
e eu tenho que mergulhar nessa exceção aninhada para buscar a real. Tenho certeza de que existe uma maneira mais fácil, mas não consigo encontrá-la.Então, como posso resolver esses problemas? Ou talvez a maneira como implementei esse manipulador de exceção global esteja completamente errada e haja uma alternativa melhor?