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:

O Tomcat ou Spring (não tem certeza de quem é o responsável) ainda está registrando a mensagem de erro. Não quero isso porque quero registrá-lo (com informações adicionais) e não quero duplicar mensagens de erro no log. Como posso impedir esse log padrão?A maneira como acesso o objeto de exceção não parece certa. Eu busco se no atributo requestjavax.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?

questionAnswers(1)

yourAnswerToTheQuestion