首先确定统一的返回类
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResponseResult<T> {
private Integer code;
private String msg;
private T date;
}
我们新建一个controller并成功访问
@RestController
public class HelloController {
@GetMapping("/hello")
public ResponseResult<?> hello(){
return new ResponseResult<>(200,"hello",null);
}
}
此时如果controller中出现异常
@RestController
public class HelloController {
@GetMapping("/hello")
public ResponseResult<?> hello(){
int num = 10/0;//由于此处余数为0,将会抛出异常
return new ResponseResult<>(200,"hello",null);
}
}
我们继续访问controler,发现达不到我们统一返回格式的效果
此时我们可以在controller中自行捕获然后返回,如下所示
@RestController
public class HelloController {
@GetMapping("/hello")
public ResponseResult<?> hello(){
try {
int num = 10/0;
}catch (Exception e){
return new ResponseResult<>(500,"出现异常",null);
}
return new ResponseResult<>(200,"hello",null);
}
}
但是如果每一个方法都需要我们单独去手动捕获,那么劳动量将会大大增加,因此我们引入全局的统一异常处理@ControllerAdive(此处使用@RestControllerAdvice,原理和@Response+@Controller相同),新建一个类
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = {Exception.class})
public ResponseResult<?> baseHandler(){
return new ResponseResult<>(555,"由全局统一异常处理器捕获",null);
}
}
此时我们再访问并没有做异常try catch处理的controller
,将会看到异常被捕获了
此处我们指定的捕获异常为Exception.class,所以所有的异常都将会被该方法给捕获,但实际开发中由于粒度太大,只能做兜底使用。
一般我们会细化粒度捕获异常,比如在value中指定捕获的异常为除0异常ArithmeticException
但是实际开发中一般自定义异常使用较多,比如登陆时用户名未找到,我们自定义一个UsernameNotFoundException,然后在GlobalExceptionHandler再定义一个方法,指定value为UsernameNotFoundException专门处理这个异常。
配置了多个异常捕获方法时springboot将会优先查询该异常的指定处理方法并执行,如果没有该异常专门的处理方法,将会执行包含该子类的异常的处理方法,比如Exception