我正在使用Tomcat作为嵌入式Web容器使用Spring 4.0.4和Spring Boot 1.0.2编写Web应用程序,我想实现一个全局异常处理,该处理将拦截所有异常并以特定方式记录它们。我的简单要求是:

  • 我想全局处理所有其他地方尚未处理的异常(例如在 Controller 异常处理程序中)。我想记录该消息,并想向用户显示自定义错误消息。
  • 我不希望Spring或Web容器本身记录任何错误,因为我想自己做。

  • 到目前为止,我的解决方案如下所示(简化,无日志记录,无重定向到错误 View ):

    @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";
        }
    }
    

    结果是, Controller 中引发的异常由unexpectedError方法正确处理,而404状态代码由notFound方法正确处理。到目前为止,还不错,但是我有以下问题:
  • Tomcat或Spring(不确定谁负责)仍在记录错误消息。我不希望那样,因为我想自己记录(带有其他信息),并且我不想在日志中重复出现错误消息。如何防止此默认日志记录?
  • 我访问异常对象的方式似乎不正确。我从请求属性javax.servlet.error.exception获取。而且这甚至不是抛出的异常,它是org.springframework.web.util.NestedServletException的一个实例,我必须深入研究此嵌套异常才能获取真实的异常。我敢肯定,有一种更简单的方法,但我找不到。

  • 那么我该如何解决这些问题呢?还是我实现此全局异常处理程序的方式是完全错误的,还有更好的选择吗?

    最佳答案

    看看ControllerAdvice
    您可以执行以下操作:

    @ControllerAdvice
    public class ExceptionHandlerController {
    
        public static final String DEFAULT_ERROR_VIEW = "error";
    
        @ExceptionHandler(value = {Exception.class, RuntimeException.class})
        public ModelAndView defaultErrorHandler(HttpServletRequest request, Exception e) {
                ModelAndView mav = new ModelAndView(DEFAULT_ERROR_VIEW);
    
            mav.addObject("datetime", new Date());
            mav.addObject("exception", e);
            mav.addObject("url", request.getRequestURL());
            return mav;
        }
    }
    

    07-28 03:19
    查看更多