• 封装全局异常处理


    1 定义错误码

    ​ 可以定义各种错误码枚举,比如业务,系统相关的报错信息

    /**
     * 错误代码
     * 错误码
     *
     * @author leovany
     * @date 2023/09/23
     */
    public enum ErrorCode {
        SUCCESS(0, "success", ""),
        ERROR_PARAMS(40000, "请求参数错误", ""),
        ERROR_NULL(40001, "请求数据为空", ""),
        ERROR_LOGIN(40100, "未登录", ""),
        ERROR_NO_AUTH(41001, "无权限", ""),
        ERROR_SYSTEM(50000, "系统内部异常", "")
        ;
    
    
        /**
         * 错误码ID
         */
        private final int code;
    
        /**
         * 错误码信息
         */
        private final String message;
    
        /**
         * 错误码描述(详情)
         */
        private final String description;
    
        ErrorCode(int code, String message, String description) {
            this.code = code;
            this.message = message;
            this.description = description;
        }
    
        public int getCode() {
            return code;
        }
    
        public String getMessage() {
            return message;
        }
    
        public String getDescription() {
            return description;
        }
    }
    
    
    • 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

    2 定义业务异常类

    • 相对于 java 的异常类,支持更多字段

      扩展了 codedescription两个字段

    • 自定义构造函数,更灵活 / 快捷的设置字段

    import com.leovany.usercenter.common.ErrorCode;
    
    /**
     * 业务异常
     * 自定义业务异常类
     *
     * @author leovany
     * @date 2023/09/23
     */
    public class BusinessException extends RuntimeException {
    
        /**
         * 错误码
         */
        private final int code;
    
        /**
         * 描述
         */
        private final String description;
    
        /**
         * 业务异常
         *
         * @param message     信息
         * @param code        错误码
         * @param description 描述
         */
        public BusinessException(String message, int code, String description) {
            super(message);
            this.code = code;
            this.description = description;
        }
    
        /**
         * 业务异常
         *
         * @param errorCode 错误代码
         */
        public BusinessException(ErrorCode errorCode) {
            super(errorCode.getMessage());
            this.code = errorCode.getCode();
            this.description = errorCode.getDescription();
        }
    
        /**
         * 业务异常
         *
         * @param errorCode   错误代码
         * @param description 描述
         */
        public BusinessException(ErrorCode errorCode, String description) {
            super(errorCode.getMessage());
            this.code = errorCode.getCode();
            this.description = description;
        }
    
        public int getCode() {
            return code;
        }
    
        public String getDescription() {
            return description;
        }
    }
    
    
    • 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
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    3 全局异常处理器

    • 通过Spring AOP实现,在调用方法前后进行额外的处理

    • 作用

      • 捕获代码中所有的异常,让前端得到更详细的业务报错信息
      • 屏蔽掉项目框架本身的异常,不暴露服务器的内部状态
      • 集中处理,比如还可以做记录日志
    import com.leovany.usercenter.common.ResultVO;
    import com.leovany.usercenter.common.ErrorCode;
    import com.leovany.usercenter.common.ResultUtils;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    
    /**
     * 全局异常处理类
     */
    @RestControllerAdvice
    @Slf4j
    public class GlobalExceptionHandler {
    
        /**
         * 处理异常-BusinessException
         * @param e
         * @return
         */
        @ExceptionHandler(BusinessException.class)
        public ResultVO<?> businessExceptionHandler(BusinessException e){
            log.error("businessException:" + e.getMessage(),e);
            return ResultUtils.error(e.getCode(),e.getMessage(),e.getDescription());
        }
    
        /**
         * 处理异常-RuntimeException
         * @param e
         * @return
         */
        @ExceptionHandler(RuntimeException.class)
        public ResultVO<?> runtimeExceptionHandler(RuntimeException e){
            log.error("runtimeException:" + e);
            return ResultUtils.error(ErrorCode.ERROR_SYSTEM,e.getMessage());
        }
    }
    
    
    • 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

    4 使用

    throw new BusinessException可以在方法中,任意地方抛出,很方便

    • 示例代码
    @PostMapping("/login")
    public ResultVO<User> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
    
        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();
    
        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            throw new BusinessException(ErrorCode.ERROR_PARAMS);
        }
        User user = userService.doLogin(userAccount, userPassword, request);
        return ResultUtils.success(user);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 代码对比

    image-20230923231424717

    5 前端请求效果

    image-20230923232720326

    总结

    ​ 通过封装全局异常处理,对异常信息做了统一处理,让前端得到更详细的业务信息,同时保证系统的安全性(不会暴露系统内部信息),在代码上对参数校验等方面提供更加方便的形式。

  • 相关阅读:
    HackTheBox - Starting Point -- Tier 0 --- Mongod
    制作路由器openwrt安装及配置
    ClickHouse部署文档
    Flink Hive Catalog操作案例
    Java并发 | 16.[基础] synchronized简述
    【LeetCode-中等题】106. 从中序与后序遍历序列构造二叉树
    c# - C#用fo-dicom对CT图像的PixelData进行处理和转换
    蓝桥杯练习题二 - 合并检测(c++)
    一个 SpringBoot 问题就干趴下了?我却凭着这份 PDF 文档吊打面试官
    springboot供应商管理系统毕业设计源码121518
  • 原文地址:https://blog.csdn.net/leovnay/article/details/133235226