当前位置: 首页 > news >正文

SpringMVC-全局异常处理

文章目录

  • 1. 全局异常处理
  • 2. 项目异常处理方案
    • 2.1 异常分类
    • 2.2 异常解决方案
    • 2.3 异常解决方案具体实现

1. 全局异常处理

  • 问题:当我们在SpingMVC代码中没有对异常进行处理时,三层架构的默认处理异常方案是将异常抛给上级调用者。也就是说Mapper层报错会将异常上抛给Service层,Service层报错会将异常上抛给Controller层,最终抛给框架之后会把各种各样的错误信息直接返回给前端,前端往往难以解析这些五花八门的异常。

  • 解决方案:SpingMVC提供了全局异常处理器,捕获不同的异常进行特定的处理。

    在这里插入图片描述

  • 实现方法:

    1. 上加@RestControllerAdvice注解,加上这个注解就代表我们定义了一个全局异常处理器,同时需要确保该类能够被Spring容器扫描到

      @RestControllerAdvice = @ControllerAdvice + @ResponseBody

      处理异常的方法返回值会转换为Json后再响应给前端

      在这里插入图片描述

    2. 在全局异常处理器当中,需要定义一个方法来捕获异常,在这个方法上需要加上注解@ExceptionHandler。通过@ExceptionHandler注解当中的value属性来指定我们要捕获的是哪一类型的异常。

      @RestControllerAdvice
      public class GlobalExceptionHandler {
          //处理异常
          @ExceptionHandler(Exception.class) //指定能够处理的异常类型
          public Result ex(Exception e){
              e.printStackTrace(); //打印堆栈中的异常信息
              //捕获到异常之后,响应一个标准的Result
              return Result.error("对不起,操作失败,请联系管理员");
          }
      }
      

2. 项目异常处理方案

2.1 异常分类

  • 因为异常的种类有很多,如果每一个异常都对应一个@ExceptionHandler,那得写多少个方法来处理各自的异常,所以我们在处理异常之前,需要对异常进行一个分类:

    • 业务异常(BusinessException)

      • 规范的用户行为产生的异常

        • 用户在页面输入内容的时候未按照指定格式进行数据填写,如在年龄框输入的是字符串

          在这里插入图片描述

      • 不规范的用户行为操作产生的异常

        • 如用户故意传递错误数据

          在这里插入图片描述

    • 系统异常(SystemException)

      • 项目运行过程中可预计但无法避免的异常
        • 比如数据库或服务器宕机
    • 其他异常(Exception)

      • 编程人员未预期到的异常,如:用到的文件不存在

        在这里插入图片描述

    将异常分类以后,针对不同类型的异常,要提供具体的解决方案:

2.2 异常解决方案

  • 业务异常(BusinessException)
    • 发送对应消息传递给用户,提醒规范操作
      • 大家常见的就是提示用户名已存在或密码格式不正确等
  • 系统异常(SystemException)
    • 发送固定消息传递给用户,安抚用户
      • 系统繁忙,请稍后再试
      • 系统正在维护升级,请稍后再试
      • 系统出问题,请联系系统管理员等
    • 发送特定消息给运维人员,提醒维护
      • 可以发送短信、邮箱或者是公司内部通信软件
    • 记录日志
      • 发消息和记录日志对用户来说是不可见的,属于后台程序
  • 其他异常(Exception)
    • 发送固定消息传递给用户,安抚用户
    • 发送特定消息给编程人员,提醒维护(纳入预期范围内)
      • 一般是程序没有考虑全,比如未做非空校验等
    • 记录日志

2.3 异常解决方案具体实现

  1. 自定义异常类:添加code属性以区分异常来自哪个业务。

    //自定义异常处理器,用于封装异常信息,对异常进行分类
    @Data
    public class SystemException extends RuntimeException{
        private Integer code;
        public SystemException(Integer code, String message) {
            super(message);
            this.code = code;
        }
    
        public SystemException(Integer code, String message, Throwable cause) {
            super(message, cause);
            this.code = code;
        }
    }
    
    //自定义异常处理器,用于封装异常信息,对异常进行分类
    @Data
    public class BusinessException extends RuntimeException{
        private Integer code;
        public BusinessException(Integer code, String message) {
            super(message);
            this.code = code;
        }
    
        public BusinessException(Integer code, String message, Throwable cause) {
            super(message, cause);
            this.code = code;
        }
    }
    
    //状态码
    public class Code {
        public static final Integer SAVE_OK = 20011;
        public static final Integer DELETE_OK = 20021;
        public static final Integer UPDATE_OK = 20031;
        public static final Integer GET_OK = 20041;
    
        public static final Integer SAVE_ERR = 20010;
        public static final Integer DELETE_ERR = 20020;
        public static final Integer UPDATE_ERR = 20030;
        public static final Integer GET_ERR = 20040;
        public static final Integer SYSTEM_ERR = 50001;
        public static final Integer SYSTEM_TIMEOUT_ERR = 50002;
        public static final Integer SYSTEM_UNKNOW_ERR = 59999;
    
        public static final Integer BUSINESS_ERR = 60002;
    }
    
    
  2. 将其他异常换成自定义异常:

    public Book getById(Integer id) {
        //模拟业务异常,包装成自定义异常
        if(id == 1){
            throw new BusinessException(Code.BUSINESS_ERR,"业务异常,用户注意相关格式");
        }
        //模拟系统异常,将可能出现的异常进行包装,转换成自定义异常
        try{
            int i = 1/0;
        }catch (Exception e){
            throw new SystemException(Code.SYSTEM_TIMEOUT_ERR,"服务器访问超时,请重试!",e);
        }
        return bookDao.getById(id);
    }
    
  3. 处理器类中处理自定义异常:

    //@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
    @RestControllerAdvice
    public class ProjectExceptionAdvice {
        @ExceptionHandler(SystemException.class)
        public Result doSystemException(SystemException ex){
            //记录日志
            //发送消息给运维
            //发送邮件给开发人员,ex对象发送给开发人员
            return new Result(ex.getCode(),null,ex.getMessage());
        }
    
        @ExceptionHandler(BusinessException.class)
        public Result doBusinessException(BusinessException ex){
            return new Result(ex.getCode(),null,ex.getMessage());
        }
    
        //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
        @ExceptionHandler(Exception.class)
        public Result doOtherException(Exception ex){
            //记录日志
            //发送消息给运维
            //发送邮件给开发人员,ex对象发送给开发人员
            return new Result(Code.SYSTEM_UNKNOW_ERR,null,"系统繁忙,请稍后再试!");
        }
    }
    

相关文章:

  • 程序化广告行业(2/89):从程序化广告深挖数据处理技巧
  • linux下文件读写操作
  • 【YOLOv8】YOLOv8改进系列(5)----替换主干网络之EfficientFormerV2
  • linux 软件安装(中)
  • JSONUtil InvocationTargetException: null
  • vscode带参数调试
  • jdk-21_linux-x64_bin.tar.gz Linux jdk21压缩包安装保姆级(详细安装教程)
  • 【AI】让deepseek_r1 671b将draw.io对应的xml数据格式转换成markdown上可以直接渲染出来的Mermaid格式
  • LSTM方法实践——基于LSTM的汽车销量时序建模与预测分析
  • 车载以太网测试-4车载以太网如何进行通信的?
  • 高级java每日一道面试题-2025年2月18日-数据库篇-MySQL 如何做到高可用方案?
  • Postgresql安装
  • 多模态融合的分类、跨模态对齐的方法
  • Spring boot创建时常用的依赖
  • flask_restx 定义任意类型参数
  • MySQL主从延迟分析
  • JVM、MySQL常见面试题(尽力局)
  • 蓝桥杯P19718-回文字符串 题解
  • 从头开始开发基于虹软SDK的人脸识别考勤系统(python+RTSP开源)(二)
  • 【HarmonyOS Next】鸿蒙应用加载SVG文件显示图标
  • 流失79载,国宝文物“子弹库帛书”(二、三卷)回归祖国
  • 新版城市规划体检评估解读:把城市安全韧性摆在更加突出位置
  • 媒体:中国女排前队长朱婷妹妹被保送浙大受质疑,多方回应
  • 市场监管总局召开平台企业支持个体工商户发展座谈会
  • 古巴外长谴责美国再次将古列为“反恐行动不合作国家”
  • 中哥两国元首共同见证签署《中华人民共和国政府与哥伦比亚共和国政府关于共同推进丝绸之路经济带和21世纪海上丝绸之路建设的合作规划》