美文网首页
Spring Boot统一异常处理

Spring Boot统一异常处理

作者: wencai | 来源:发表于2018-07-06 16:36 被阅读0次

    Spring通过@ControllerAdvice和@ExceptionHandler两个注解即可实现异常的统一处理。

    一、用法介绍

      @ControllerAdvice和@ExceptionHandler可拦截异常,通过这两个注解可实现对异常的自定义处理。


    二、示例

    1.需求

      提供两种异常返回方式:对RESTful风格返回特定的json格式;对text/html风格,返回特定的页面。

    2.实现

    第一步:定义全局异常捕获类

    @RestControllerAdvice
    public class GlobalExceptionHandle {
    
        private Logger logger = LoggerFactory.getLogger("GlobalExceptionHandler");
    
        public ModelAndView defaultErrorHandler(HttpServletRequest req, Exception e){
            ModelAndView mav = new ModelAndView();
            mav.addObject("msg","异常咯");
            mav.setViewName("error");
            return mav;
        }
    
        @ExceptionHandler(BaseException.class)
        public Object baseErrorHandler(HttpServletRequest req, Exception e) throws Exception {
            logger.error("---BaseException Handler---Host {} invokes url {} ERROR: {}", req.getRemoteHost(), req.getRequestURL(), e.getMessage());
            return e.getMessage();
        }
    }
    

    第二步:定义异常处理类

    public class BaseException extends Exception {
        public BaseException(String message) {
            super(message);
        }
    }
    

    第三步:定义Controller测试异常

    @RequestMapping("/ex")
        public Object throwIOException() throws Exception {
            throw new IOException("This is IOException.");
        }
    

    第四步:为Controller定义特定的异常@ExceptionHandler
    在Controller中增加以下代码:

     @RequestMapping("/ex5")
        public Object throwNullPointerException() throws Exception {
            throw new NullPointerException("This is NullPointerException.");
        }
    
        @ExceptionHandler(NullPointerException.class)
        public String controllerExceptionHandler(HttpServletRequest req, Exception e) {
            logger.error("---ControllerException Handler---Host {} invokes url {} ERROR: {}", req.getRemoteHost(), req.getRequestURL(), e.getMessage());
            return e.getMessage();
        }
    

    Tips:在SpringBoot中,当用户访问一个不存在的链接时,Spring默认将页面重定向到/error上,而不会抛出异常。既然如此,可以告诉SpringBoot,当出现404错误时,抛出一个异常即可。在application.properties中添加如下代码:

    spring.mvc.throw-exception-if-no-handler-found=true
    spring.resources.add-mappings=false
    

    三、源码解析

    1.默认情况,SpringBoot为两种情况提供了不同的响应方式。
      1)浏览器请求一个不存在的页面或服务端发生异常时,一般情况浏览器默认会发送的请求头中Accept: text/html,所以SpringBoot默认会响应一个html文档内容,称作“Whitelabel Error Page”。
      2)使用postman工具或者js发送请求一个不存在的url或者服务端发生异常时,SpringBoot会返回如下格式的Json字符串:


    222.png

    2.原理很简单:
      SpringBoot默认提供了程序出错的映射路径/error。这个/error请求会在BasicErrorController中处理,其内部是通过判断请求头中的Accept内容是text/html还是其他,来决定返回页面视图还是JSON消息内容。代码如下:

    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
            HttpStatus status = this.getStatus(request);
            Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.TEXT_HTML)));
            response.setStatus(status.value());
            ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
            return modelAndView != null ? modelAndView : new ModelAndView("error", model);
        }
    
        @RequestMapping
        @ResponseBody
        public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
            Map<String, Object> body = this.getErrorAttributes(request, this.isIncludeStackTrace(request, MediaType.ALL));
            HttpStatus status = this.getStatus(request);
            return new ResponseEntity(body, status);
        }
    

    如何自定义Whitelabel Error Page
      直接在/resources/template下面创建error.html即可覆盖Whitelabel Error Page的错误页面。如果想定义

    四、更多详情

    https://segmentfault.com/a/1190000006749441
    https://blog.csdn.net/zzz___bj/article/details/80368071
    http://tengj.top/2018/05/16/springboot13/#%E4%BB%8B%E7%BB%8DSpring-Boot%E9%BB%98%E8%AE%A4%E7%9A%84%E5%BC%82%E5%B8%B8%E5%A4%84%E7%90%86%E6%9C%BA%E5%88%B6

    相关文章

      网友评论

          本文标题:Spring Boot统一异常处理

          本文链接:https://www.haomeiwen.com/subject/dvrbuftx.html