Springboot:统一异常处理

1.简洁

软件开发过程中,不可避免的是需要处理各种异常,就我自己来说,至少有一半以上的时间都是在处理各种异常情况,所以代码中就会出现大量的try {...} catch {...} finally {...} 代码块,不仅有大量的冗余代码,而且还影响代码的可读性

我们可以不显式的处理异常,优雅的处理异常吗

2.统一异常处理

Spring在3.2版本增加了一个注解@ControllerAdvice,可以与@ExceptionHandler@InitBinder@ModelAttribute 等注解注解配套使用

不过跟异常处理相关的只有注解@ExceptionHandler,从字面上看,就是 异常处理器 的意思,其实际作用也是:若在某个Controller类定义一个异常处理方法,并在方法上添加该注解,那么当出现指定的异常时,会执行该处理异常的方法,其可以使用springmvc提供的数据绑定,比如注入HttpServletRequest等,还可以接受一个当前抛出的Throwable对象。

3.流程

在独立的某个地方,比如单独一个类,定义一套对各种异常的处理机制,然后在类的签名加上注解@ControllerAdvice,统一对 不同阶段的不同异常 进行处理。这就是统一异常处理的原理。

注意到上面对异常按阶段进行分类,大体可以分成:进入Controller前的异常 和 Service 层异常,具体可以参考下图:

Springboot:统一异常处理_第1张图片

 4.示例

/**
 * 全局异常处理
 */
//表示处理带有RestController Controller这两种注解的类
@ControllerAdvice(annotations = {RestController.class, Controller.class})
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {

    /**
     * 异常处理方法
     * 该异常可以捕获sql中的insert中unique字段重复的异常
     * @return
     */
    @ExceptionHandler(SQLIntegrityConstraintViolationException.class)
    public R exceptionHandler(SQLIntegrityConstraintViolationException ex){
        log.error(ex.getMessage());

        if(ex.getMessage().contains("Duplicate entry")){
            String[] split = ex.getMessage().split(" ");
            String msg = split[2] + "已存在";
            return R.error(msg);
        }

        return R.error("未知错误");
    }

    /**
     * 异常处理方法
     * @return
     */
    @ExceptionHandler(CustomException.class)
    public R exceptionHandler(CustomException ex){
        log.error(ex.getMessage());

        return R.error(ex.getMessage());
    }

}

参考:https://www.jianshu.com/p/3f3d9e8d1efa

你可能感兴趣的:(Springboot,spring,boot,spring,java)