Spring Boot项目全局异常处理方式

SpringBoot中,@ControllerAdvice 即可开启全局异常处理,使用该注解表示开启了全局异常的捕获,我们只需在自定义一个方法使用@ExceptionHandler注解然后定义捕获异常的类型即可对这些捕获的异常进行统一的处理。

添加@ControllerAdvice自定义全局异常处理器

@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());
    }
}

    • 全局异常处理器注解说明:

@ExceptionHandler(value = MyException.class) -- 注解类型
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) -- 错误码
@ResponseBody --  返回json
@ControllerAdvice -- 顾名思义,这是一个增强的 Controller。使用这个 Controller ,可以实现三个方面的功能:
1.全局异常处理
2.全局数据绑定
3.全局数据预处理

定义枚举类

@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;
    }
}

自定义异常类

@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;
    }
}

自定义数据返回类

@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;
    }
}

测试

@GetMapping("/info/{attrId}")
public ProductAttr getAttrIdById(@PathVariable("attrId") Long attrId){
    // throw new ServiceException(ReturnCode.INVALID_TOKEN); //抛出自定义异常
    int i = 10 / 0;
    return productAttrService.getById(attrId);
}

返回数据

{
    "status": 500,
    "message": "/ by zero",
    "data": null,
    "timestamp": 1711618149074
}

© 版权声明
THE END
喜欢就支持以下吧
点赞7 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容