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

SpringBoot自定义全局异常处理器

文章目录

  • 一、介绍
  • 二、实现
      • 1. 定义全局异常处理器
      • 2. 自定义异常类
  • 三、使用
  • 四、疑问

一、介绍

Springboot框架提供两个注解帮助我们十分方便实现全局异常处理器以及自定义异常

  • @ControllerAdvice@RestControllerAdvice(推荐)
  • @ExceptionHandler

二、实现

1. 定义全局异常处理器

定义GlobalExceptionHandler类,拦截所有异常。
@RestControllerAdvice注解使得你可以在GlobalExceptionHandler 中处理异常,@ExceptionHandle注解用于将指定异常绑定到处理的函数上。如下使用@ExceptionHandler(Exception.class)即对所有异常进行捕获处理。

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {@ExceptionHandler(Exception.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public RestErrorResponse exception(Exception e){//record loglog.error("系统异常{}", e.getMessage(),e);//decode errorExceptionString errMessage = "系统异常";return new RestErrorResponse(errMessage);}
}
@Data
@AllArgsConstructor
public class RestErrorResponse implements Serializable {private String errMessage;
}

事实上,写到这里已经可以用了,RestErrorResponse 用来承载错误信息到前端,因为@RestControllerAdvice已经包含了@ResponseBody

2. 自定义异常类

继承RuntimeException 异常类写一个自定义的异常类。这么做主要是能够使用自定义的枚举类来更优雅的抛出错误。

@Data
public class XueChengPlusException extends RuntimeException {private String errMessage;public XueChengPlusException() {super();}public XueChengPlusException(String errMessage) {super(errMessage);this.errMessage = errMessage;}public static void cast(CommonError commonError){throw new XueChengPlusException(commonError.getErrMessage());}public static void cast(String errMessage){throw new XueChengPlusException(errMessage);}}
@Getter
public enum CommonError {UNKOWN_ERROR("执行过程异常,请重试。"),PARAMS_ERROR("非法参数"),OBJECT_NULL("对象为空"),QUERY_NULL("查询结果为空"),REQUEST_NULL("请求参数为空");private String errMessage;private CommonError( String errMessage) {this.errMessage = errMessage;}
}

同时,对于GlobalExceptionHandler 也要做一些修改,一方面处理自定义异常,另一方处理其余异常。

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {@ExceptionHandler(XueChengPlusException.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public RestErrorResponse customException(XueChengPlusException e){//record loglog.error("系统异常{}", e.getErrMessage(),e);//decode errorExceptionString errMessage = e.getErrMessage();return new RestErrorResponse(errMessage);}@ExceptionHandler(Exception.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public RestErrorResponse exception(Exception e){//record loglog.error("系统异常{}", e.getMessage(),e);//decode errorExceptionString errMessage = CommonError.UNKOWN_ERROR.getErrMessage();return new RestErrorResponse(errMessage);}
}

三、使用

在程序中任意地方抛出异常,controllerservicedao层都可以,比如

throw new RuntimeException("价格不能为空且必须大于0");

这时走的就是

	@ExceptionHandler(Exception.class)public RestErrorResponse exception(Exception e)

除此之外,可以这样抛出自定义异常,比如

XueChengPlusException.cast(CommonError.PARAMS_ERROR);
XueChengPlusException.cast("其他的消息");
throw new XueChengPlusException(CommonError.OBJECT_NULL.getErrMessage());
throw new XueChengPlusException("其他的消息");

这时走的就是

	@ExceptionHandler(XueChengPlusException.class)public RestErrorResponse customException(XueChengPlusException e)

四、疑问

Q:疑问,XueChengPlusException异常类继承自RuntimeException ,而RuntimeException 继承自Exception,为什么触发customException而不是exception?

在这个全局异常处理器中,当抛出一个XueChengPlusException异常时,它会被customException(XueChengPlusException e)方法处理,而不是exception(Exception e)方法。

这是因为Spring框架的异常处理机制会优先匹配最具体的异常类型。在您的代码中,XueChengPlusExceptionRuntimeException(以及Exception)的子类,因此它更具体。所以,当抛出一个XueChengPlusException异常时,Spring会优先调用处理XueChengPlusException的方法,而不是处理Exception的方法。

这种行为确实表明全局异常处理器有一定的优先级和覆盖逻辑。具体来说,处理器会优先处理更具体的异常类型,如果没有找到匹配的处理器,那么它会寻找处理更一般异常类型的处理器。
在这里插入图片描述

相关文章:

  • 基础算法--搜索与图论(2)
  • 盘古信息IMS OS 数垒制造操作系统+ 产品及生态部正式营运
  • 黑马程序员-瑞吉外卖-day5
  • SpringBoot中从HikariCP迁移到Oracle UCP指南
  • STM32 PWM驱动设计
  • OJ_阶乘的和
  • 【重点问题】攻击面发现及管理
  • SpringBoot 整合RabbitMQ 之延迟队列实验
  • Jenkins上跑自动化项目,case出现错误时,导致项目运行时间过长,该如何处理?
  • diffusion 和 gan 的优缺点对比
  • Python系列(9)—— 比较运算符
  • 知识笔记(九十七)———什么是实体符???
  • 【算法专题】动态规划之回文子串问题
  • c#定义特性,通过反射获取特性
  • 基于SSM的网络办公系统(有报告)。Javaee项目。ssm项目。
  • [译]Python中的类属性与实例属性的区别
  • 【跃迁之路】【733天】程序员高效学习方法论探索系列(实验阶段490-2019.2.23)...
  • Android优雅地处理按钮重复点击
  • dva中组件的懒加载
  • JavaScript DOM 10 - 滚动
  • JS字符串转数字方法总结
  • Lucene解析 - 基本概念
  • nodejs:开发并发布一个nodejs包
  • NSTimer学习笔记
  • oldjun 检测网站的经验
  • SpriteKit 技巧之添加背景图片
  • Stream流与Lambda表达式(三) 静态工厂类Collectors
  • windows下如何用phpstorm同步测试服务器
  • 大快搜索数据爬虫技术实例安装教学篇
  • 计算机常识 - 收藏集 - 掘金
  • 力扣(LeetCode)21
  • 码农张的Bug人生 - 初来乍到
  • 使用Tinker来调试Laravel应用程序的数据以及使用Tinker一些总结
  • 为什么要用IPython/Jupyter?
  • 学习Vue.js的五个小例子
  • 怎样选择前端框架
  • Salesforce和SAP Netweaver里数据库表的元数据设计
  • 蚂蚁金服CTO程立:真正的技术革命才刚刚开始
  • ​批处理文件中的errorlevel用法
  • # Apache SeaTunnel 究竟是什么?
  • # Panda3d 碰撞检测系统介绍
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • (10)STL算法之搜索(二) 二分查找
  • (13)Latex:基于ΤΕΧ的自动排版系统——写论文必备
  • (PHP)设置修改 Apache 文件根目录 (Document Root)(转帖)
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (ros//EnvironmentVariables)ros环境变量
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • (转) ns2/nam与nam实现相关的文件
  • (转)linux自定义开机启动服务和chkconfig使用方法
  • *p=a是把a的值赋给p,p=a是把a的地址赋给p。
  • .babyk勒索病毒解析:恶意更新如何威胁您的数据安全