我们在以上的开发中,统一使用Result返回固定的数据格式给到前端,但是由于程序可能会出现BUG等问题,会导致最终返回给前端的数据,在异常情况下就又不统一了
为了实现在异常情况出现时,也能正常给前端返回统一的数据格式,我们需要使用 异常处理器
定义异常处理器需要使用@RestControllerAdvice注解,代表被修饰的类是一个可以处理全局异常的类:
// 定义一个类,专门用于处理或接管异常
// 为了表明这个类可以专门处理异常,需要添加以下注解
@RestControllerAdvice
public class MyExceptionHandler {}
使用了以上注解的类,就可以接收系统中出现的异常了,但是异常出现以后,怎么处理就需要专门的处理方法来处理了.
我们可以定义一个方法,使用@ExceptionHandler注解来修饰,并且标明它可以处理什么类型的异常:
// 定义一个类,专门用于处理或接管异常
// 为了表明这个类可以专门处理异常,需要添加以下注解
@RestControllerAdvice
public class MyExceptionHandler {// 接管异常后,为了能够干点什么,需要定义处理方法进行异常逻辑处理(即,出了问题应该怎么办)// 使用@ExceptionHandler注解标明此方法处理的是何种异常@ExceptionHandler(Exception.class)public Result doException(Exception ex) {return new Result(Code.ERROR, "出问题啦:" + ex.getMessage(), null);}
}
以上被@ExceptionHandler修饰的方法,可以处理任何异常。因为它的参数是Exception.class。
接管异常后,SpringBoot框架会自动把异常处理对象注入到方法形参ex上,我们可以直接使用此异常对象
但是以上使用,@ExceptionHandler(Exception.class)来处理异常,就太宽泛了,怎么能处理更加精确的异常呢?
可以写专门的方法,使用@ ExceptionHandler注解标明接管精准的异常:
// 定义一个类,专门用于处理或接管异常
// 为了表明这个类可以专门处理异常,需要添加以下注解
@RestControllerAdvice
public class MyExceptionHandler {// 如果这里定义了更加精确的异常处理方法// 优先会由精确方法处理@ExceptionHandler(ArithmeticException.class)public Result doArithmeticException(ArithmeticException ex) {return new Result(Code.ERROR, "数学运算错误", null);}// 接管异常后,为了能够干点什么,需要定义处理方法进行异常逻辑处理(即,出了问题应该怎么办)// 使用@ExceptionHandler注解标明此方法处理的是何种异常@ExceptionHandler(Exception.class)public Result doException(Exception ex) {return new Result(Code.ERROR, "出问题啦:" + ex.getMessage(), null);}
}
如果出现的是ArithmeticException类型的异常,doArithmeticException()方法就会被调用。那么最后的托管的doExeption()方法就不被调用了。
最后还有一个问题,我们总不能在异常处理器中,把所有的异常情况都列出来吧?
那时不可能的,太麻烦了.此时我们可以将异常收纳成自己项目里的异常类型:
定义一个自己的异常类:
@Data
public class BusinessException extends RuntimeException{private Integer code;// 重写RuntimeException的两个构造方法public BusinessException(Integer code, String message){super(message);this.code = code;}public BusinessException(Integer code, String message, Throwable cause) {super(message, cause);this.code = code;}}
在出现异常的地方捕获异常后,再抛出我们自己定义的异常即可.
此时我们就可以统一接收自己的异常了
// 定义一个类,专门用于处理或接管异常
// 为了表明这个类可以专门处理异常,需要添加以下注解
@RestControllerAdvice
public class MyExceptionHandler {// 接收我们自己定义的异常@ExceptionHandler(BusinessException.class)public Result doMyException(BusinessException ex){return new Result(ex.getCode(), ex.getMessage(), null);}// 如果这里定义了更加精确的异常处理方法// 优先会由精确方法处理@ExceptionHandler(ArithmeticException.class)public Result doArithmeticException(ArithmeticException ex) {return new Result(Code.ERROR, "数学运算错误", null);}// 接管异常后,为了能够干点什么,需要定义处理方法进行异常逻辑处理(即,出了问题应该怎么办)// 使用@ExceptionHandler注解标明此方法处理的是何种异常@ExceptionHandler(Exception.class)public Result doException(Exception ex) {return new Result(Code.ERROR, "出问题啦:" + ex.getMessage(), null);}
}