• Spring - 全局异常处理器的使用


    一. 自定义异常和全局处理

    1.1 自定义异常类

    首先我们定义一个接口,规范了自定义异常的几种函数:

    public interface CommonError {
        int getErrorCode();
        String getErrorMsg();
        CommonError setErrMsg(String errMsg);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    然后我们可以自定义一个枚举异常类,定义了对应的异常原因和code代码:

    public enum EmBusinessError implements CommonError {
        // 通用错误类型 1000x
        UNKNOWN_ERROR(10000, "未知错误"),
        // 类型为数据库操作异常 2000x
        DATA_ERROR(20000, "数据库操作失败"),
        DATA_INSERT_ERROR(20001, "数据库插入异常"),
        DATA_DELETE_ERROR(20002, "数据库删除异常"),
        DATA_UPDATE_ERROR(20003, "数据库更新异常"),
        DATA_SELECT_ERROR(20004, "数据库查询异常"),
        // 业务失败 3000x
        USER_NOT_EXIST(30001, "用户不存在"),
        // 验权失败 4000x
        USER_AUTH_ERROR(40001, "验权失败"),
        USER_PERMISSION_ERROR(40002, "权限不足"),
        SHIRO_USER_AUTH_ERROR(40003, "shiro认证失败"),
        ;
    
        EmBusinessError(int errCode, String errMsg) {
            this.errCode = errCode;
            this.errMsg = errMsg;
        }
    
        private int errCode;
        private String errMsg;
    
    
        @Override
        public int getErrorCode() {
            return errCode;
        }
    
        @Override
        public String getErrorMsg() {
            return errMsg;
        }
    
        @Override
        public CommonError setErrMsg(String errMsg) {
            this.errMsg = errMsg;
            return this;
        }
    }
    
    • 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
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    接下来就可以自定义异常了:

    public class BusinessException extends RuntimeException implements CommonError {
    
        private CommonError commonError;
    
        // 直接接受EmBusinessError的传参用于构造业务异常
        public BusinessException(CommonError commonError) {
            super();
            this.commonError = commonError;
        }
    
        // 接受自定义errMsg的方式构造业务异常
        public BusinessException(CommonError commonError, String errorMsg) {
            super();
            this.commonError = commonError;
            this.commonError.setErrMsg(errorMsg);
        }
    
        @Override
        public int getErrorCode() {
            return this.commonError.getErrorCode();
        }
    
        @Override
        public String getErrorMsg() {
            return this.commonError.getErrorMsg();
        }
    
        @Override
        public CommonError setErrMsg(String errMsg) {
            this.commonError.setErrMsg(errMsg);
            return this;
        }
    }
    
    • 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
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    1.2 统一风格的返回格式

    我们自定义一个CommonReturnType类,无论是正常的请求还是异常的捕获,我们都用这个类来完成构建Response对象。

    public class CommonReturnType {
    
        // 返回请求处理结果
        private String status;
        // 返回数据
        private Object data;
    
        public static CommonReturnType creat(Object result) {
            return CommonReturnType.creat(result, "success");
        }
    
        public static CommonReturnType fail(CommonError error) {
            return fail(error.getErrorCode(), error.getErrorMsg());
        }
    
        public static CommonReturnType fail(CommonError error, String errorMsg) {
            return fail(error.getErrorCode(), errorMsg);
        }
    
        public static CommonReturnType fail(Integer errorCode, String errorMsg) {
            CommonReturnType type = new CommonReturnType();
            Map<String, Object> responseData = new HashMap<>();
            responseData.put("errorCode", errorCode);
            responseData.put("errorMsg", errorMsg);
            type.setStatus("fail");
            type.setData(responseData);
            return type;
        }
    
        public static CommonReturnType creat(Object result, String status) {
            CommonReturnType type = new CommonReturnType();
            type.setData(result);
            type.setStatus(status);
    
            return type;
        }
    
        public String getStatus() {
            return status;
        }
    
        public void setStatus(String status) {
            this.status = status;
        }
    
        public Object getData() {
            return data;
        }
    
        public void setData(Object data) {
            this.data = data;
        }
    
    
    • 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
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    1.3 全局处理

    我们自定义一个ExceptionController,加上@RestControllerAdvice注解。

    @RestControllerAdvice
    @Slf4j
    public class ExceptionController {
        // 捕获自定义异常
        @ExceptionHandler(BusinessException.class)
        public CommonReturnType businessException(BusinessException e) {
            return CommonReturnType.fail(e);
        }
    
        // 捕捉其他所有异常
        @ExceptionHandler(Exception.class)
        public CommonReturnType globalException(Exception e) {
            return CommonReturnType.fail(EmBusinessError.UNKNOWN_ERROR.getErrorCode(),e.getMessage());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    那么我们在业务代码上,如果想抛出自定义异常,就可以:

    public void process(){
    	// 业务处理
    	if(xxx){
    		throw new BusinessException(EmBusinessError.USER_NOT_EXIST);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果是正常的接口返回:

    @PostMapping("/login")
    public CommonReturnType login() {
        Map<String, String> map = new HashMap<>();
        map.put("msg", "Success");
    	User user = new User();
        user.setPhone("123456");
        map.put("data", user);
        return CommonReturnType.creat(map);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
  • 相关阅读:
    Oracle Primavera Unifier 23.6 新特征
    程序员简历编写指南(超详细)
    【Vue3 源码解析】to 系列全家桶
    XoT:一种新的大语言模型的提示技术
    HTML的学习-2|HTML 标签(上)
    【MySQL】# 自定义变量、一行数据与多行的转换、IF函数
    基础设施建设-企业级全栈测试平台的最佳实践
    MATLAB programming interface for STK software stkInit()
    .NET周刊【11月第2期 2023-11-12】
    iNavFlight之MSP DJI协议分析
  • 原文地址:https://blog.csdn.net/Zong_0915/article/details/126745895