SpringBoot中,@ControllerAdvice 即可开启全局异常处理,使用该注解表示开启了全局异常的捕获,我们只需在自定义一个方法使用@ExceptionHandler注解然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。
添加@ControllerAdvice自定义全局异常处理器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| @RestControllerAdvice public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public ResultData<String> exception(Exception e){ return ResultData.fail(ReturnCode.RC500.getCode(), e.getMessage()); }
@ExceptionHandler(ServiceException.class) public ResultData<String> serviceException(ServiceException e){ return ResultData.fail(e.getCode(), e.getMessage()); } }
|
1 2 3 4 5 6 7
| @ExceptionHandler(value = MyException.class) -- 注解类型 @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) -- 错误码 @ResponseBody -- 返回json @ControllerAdvice -- 顾名思义,这是一个增强的 Controller。使用这个 Controller ,可以实现三个方面的功能: 1.全局异常处理 2.全局数据绑定 3.全局数据预处理
|
定义枚举类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| @Getter public enum ReturnCode { RC100(100, "操作成功"), RC999(999, "操作失败"), RC200(200, "服务开启限流保护,请稍后再试!"), RC201(201, "服务开启降级保护,请稍后再试!"), RC202(202, "热点参数限流,请稍后再试!"), RC203(203, "系统规则不满足要求,请稍后再试!"), RC204(204, "系统规则不通过,请稍后再试!"), RC403(403, "无访问权限,请联系管理员授予权限"), RC401(401, "匿名用户访问无权限资源异常"), RC500(500, "系统错误,请稍后重试"),
INVALID_TOKEN(2001, "访问令牌不合法"), ACCESS_DENIED(2003, "没有权限访问该资源"), CLIENT_AUTHENTICATION_FAILED(1001, "客户端认证失败"), USERNAME_OR_PASSWORD_ERROR(1002, "用户名或密码错误"), UNSUPPORTED_GRANT_TYPE(1003, "不支持的认证模式");
private final int code; private final String message; ReturnCode(int code, String message){ this.code = code; this.message = message; } }
|
自定义异常类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| @Getter public class ServiceException extends RuntimeException{
private final int code;
public ServiceException(ReturnCode returnCode){ super(returnCode.getMessage()); this.code = returnCode.getCode(); }
public ServiceException(Integer code, String message){ super(message); this.code = code; } }
|
自定义数据返回类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| @Data public class ResultData<T> { private int status; private String message; private T data; private long timestamp;
public ResultData(){ this.timestamp = System.currentTimeMillis(); }
public static <T> ResultData<T> success(T data){ ResultData<T> resultData = new ResultData<>(); resultData.setStatus(ReturnCode.RC100.getCode()); resultData.setMessage(ReturnCode.RC100.getMessage()); resultData.setData(data); return resultData; }
public static <T> ResultData<T> fail(int code, String message){ ResultData<T> resultData = new ResultData<>(); resultData.setStatus(code); resultData.setMessage(message); return resultData; } }
|
测试
1 2 3 4 5 6
| @GetMapping("/info/{attrId}") public ProductAttr getAttrIdById(@PathVariable("attrId") Long attrId){ int i = 10 / 0; return productAttrService.getById(attrId); }
|
返回数据
1 2 3 4 5 6
| { "status": 500, "message": "/ by zero", "data": null, "timestamp": 1711618149074 }
|