首页 > 其他分享 >统一异常处理【学习aop解决异常】

统一异常处理【学习aop解决异常】

时间:2024-03-27 22:22:51浏览次数:25  
标签:code 自定义 学习 处理器 aop Integer 异常 public

1、统一异常处理

任何一个位置都有可能出现异常,这是不能避免的

将异常不断往外抛,数据层抛到业务层,业务层抛到表现层,controller抛到异常处理器统一处理并将结果返回给前端

异常种类繁多,需要进行分类,不能每一个异常对应一种处理方法

表现层处理异常,每个异常单独,代码量大且意义不强,使用AOP解决

异常处理器可以集中统一的处理项目中出现的异常

异常处理器类返回结果给前端,需要确保SpringMvcConfig能够扫描到异常处理器类

//用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
    //除了自定义的异常处理器,保留对Exception类型的异常处理,用于处理非预期的异常
    //拦截异常的种类
    @ExceptionHandler(Exception.class)
    public Result doException(Exception ex){
      	System.out.println("出现了异常");
        return new Result (code,data)
    }
}

2、注解说明

@RestControllerAdvice
  1. Rest风格开发的控制器增强类定义上方,为Rest风格开发的控制器类做增强
  2. 自带@ResponseBody+@Component
@ExceptionHandler
  1. 专用于异常处理的控制器方法上方
  2. 设置指定异常的处理方案,功能等同于控制器方法,出现异常后终止原始控制器执行,并转入当前方法执行
  3. 此类方法可以根据处理的异常不同,制作多个方法分别处理对应的异常

3、异常的种类


异常的种类及出现异常的原因:

  • 框架内部抛出的异常:因使用不合规导致
  • 数据层抛出的异常:因外部服务器故障导致(例如:服务器访问超时)
  • 业务层抛出的异常:因业务逻辑书写错误导致(例如:遍历业务书写操作,导致索引异常等)
  • 表现层抛出的异常:因数据收集、校验等规则导致(例如:不匹配的数据类型间导致异常)
  • 工具类抛出的异常:因工具类书写不严谨不够健壮导致(例如:必要释放的连接长期未释放等)

异常种类:

  • 业务异常(BusinessException)

    • 规范的用户行为产生的异常:用户在页面输入内容的时候未按照指定格式进行数据填写,如在年龄框输入的是字符串
    • 不规范的用户行为操作产生的异常:如用户故意传递错误数据
  • 系统异常(SystemException)

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

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

针对不同异常,提供具体的解决方案:

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

4、处理异常

  1. 先通过自定义异常,完成BusinessException和SystemException的定义
  2. 将其他异常包装成自定义异常类型
  3. 在异常处理器类中对不同的异常进行处理
步骤1:自定义异常类
  • 让自定义异常类继承RuntimeException的好处是,后期在抛出这两个异常的时候,就不用在try...catch...或throws了
  • 自定义异常类中添加code属性的原因是为了更好的区分异常是来自哪个业务的
//自定义异常处理器,用于封装异常信息,对异常进行分类
public class SystemException extends RuntimeException{
    private Integer code;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = 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;
    }

}

//自定义异常处理器,用于封装异常信息,对异常进行分类
public class BusinessException extends RuntimeException{
    private Integer code;

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = 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;
    }

}
步骤2:将其他异常包成自定义异常

假如在BookServiceImpl的getById方法抛异常了,该如何来包装呢?

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

具体的包装方式有:

  • 方式一:try{}catch(){}在catch中重新throw我们自定义异常即可。
  • 方式二:直接throw自定义异常即可

上面为了使状态码code看着更专业些,我们在Code类中再新增需要的属性

public class Code {
    public static final Integer SYSTEM_UNKNOW_ERR = 59999;
    public static final Integer BUSINESS_ERR = 60002;
}
步骤3:处理器类中处理自定义异常
//@RestControllerAdvice用于标识当前类为REST风格对应的异常处理器
@RestControllerAdvice
public class ProjectExceptionAdvice {
    //@ExceptionHandler用于设置当前处理器类对应的异常类型
    @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,"系统繁忙,请稍后再试!");
    }
}

标签:code,自定义,学习,处理器,aop,Integer,异常,public
From: https://www.cnblogs.com/lm02/p/18100423

相关文章

  • 自学(网络安全)黑客——高效学习2024
    01什么是网络安全网络安全可以基于攻击和防御视角来分类,我们经常听到的“红队”、“渗透测试”等就是研究攻击技术,而“蓝队”、“安全运营”、“安全运维”则研究防御技术。无论网络、Web、移动、桌面、云等哪个领域,都有攻与防两面性,例如Web安全技术,既有Web渗透,也有W......
  • 【HTML】标签学习 (上.4)
    (注:续接【HTML】标签学习(上.3))(大家好哇,今天我们将继续来学习HTML的相关知识,大家可以在评论区进行互动答疑哦~加油!......
  • JVM学习
    1.1 JVM种类重用HOTSPOT。还有些列入IBM开发的灯。 1.4JVM和操作系统的关系 1.5JVMJREJDKJDK->JRE->JVM开发需要JDK,运行需要JRE 1.6JVM虚拟机规范JVM是栈结构。JVM翻译字节码有两种方式,解释执行,还有一种是JIT。 1.7JVM整体架构程序计数器......
  • 解锁社交媒体图像内容的深度学习之道
            社交媒体已经成为我们日常生活中不可或缺的一部分,人们通过分享图片、视频和文字来交流和表达自己。然而,这些海量的图像数据中蕴含着大量的信息和情感,而要从中准确地提取和理解这些信息,就需要借助先进的技术手段。深度学习作为人工智能领域的热门技术之一,为社交......
  • Python学习——例题详解1、字符串简单加密和解密
    1、加密原理    基于按位异或(^),对字符串进行简单的加密算法原理:ord('A')^ord('P')#加密,运算结果:17chr(17^ord('p'))#解密,运算结果:‘A’2、例题    给定字符串text作为明文(要加密的原文,同上述A)和key作为密钥(同上述P),使用按位异或循环处理text的每一个......
  • 深度学习第二周:CIFAR10彩色图片识别
    一、前期准备1.设置GPUimporttorchimporttorch.nnasnnimportmatplotlib.pyplotaspltimporttorchvision#设置硬件设备,如果有GPU则使用,没有则使用cpudevice=torch.device("cuda"iftorch.cuda.is_available()else"cpu")Output:device(type='cuda&#......
  • Python学习——访问命令行参数、标准输入输出
    一、sys模块    通过sys.argv()函数访问命令行参数,sys.argv()生成的是一个列表,argv[0]访问脚本,argv[1]访问第一个参数,argv[2]访问第二个参数。例1、通过调用命令行参数n,生成n个随机数。#访问命令行importsys,randomn=int(sys.argv[1])#调用命令行第一个参数,即n......
  • redis+aop实现接口防刷(幂等)
    幂等和接口防刷概念这两者其实是属于不同的场景但是在一些情况下,实现方式上有异曲同工之妙。防刷顾名思义,想让某个接口某个人在某段时间内只能请求N次。一般是对一些不发人员用脚本对接口进行大量请求,或者说利用脚本进行秒杀。幂等幂等的数学概念幂等是源于一种数学概念......
  • DDPG强化学习算法应用到TORCS仿真平台
    一、DDPG算法介绍1.前身DQN算法在介绍DDPG算法之前,需要首先明确它的前身DQN算法。DQN(DeepQ-Network)是一种用于强化学习的深度学习算法,由DeepMind公司开发。它结合了深度学习和Q-learning算法,旨在解决复杂环境下的强化学习问题。DQN算法在解决复杂环境下的强化学习问题方面取......
  • 【异常】IDEA链接TDengine提示SQLException: JNI ERROR (0x2354): Version not compat
    一、异常内容TDEngine提示SQLException:JNIERROR(0x2354):VersionnotcompatibleCausedby:java.sql.SQLException:JNIERROR(0x2354):Versionnotcompatible atcom.taosdata.jdbc.TSDBError.createSQLException(TSDBError.java:90) atcom.taosdata.jdbc.TS......