Spring Boot 使用断言抛出自定义异常,优化异常处理机制
文章目录
- 什么是断言?
- 什么是异常?
- 基于断言实现的异常处理机制
- 创建自定义异常类
- 创建全局异常处理器
- 创建自定义断言类
- 创建响应码类
- 创建工具类
- 测试效果
什么是断言?
实际上,断言(Assertion)是在Java 1.4 版本引入的特性,它为开发人员提供了一种简单的机制来进行代码预期条件的验证和调试。
Java 1.4 版本于2002年发布,它引入了许多新功能和改进,其中之一就是断言。断言的目的是在程序中进行可验证的内部检查,以确保代码的正确性和可靠性。
断言最早是在1989年由美国计算机科学家C.A.R. Hoare提出的概念,称为"断言语句"。然后,在Java 1.4版本中,Sun Microsystems将其引入到Java编程语言中,并添加了关键字assert用于表示断言。
使用assert关键字,开发人员可以在代码中编写断言语句,以检查程序的状态或条件是否满足预期。如果断言失败,会抛出一个AssertionError异常,提示开发人员该断言点存在问题。
例如org.springframework.util.Assert是Spring Framework中的一个工具类,用于进行参数校验和断言判断。它是一个包含静态方法的最终类。
在org.springframework.util.Assert类中,提供了一系列静态方法用于进行断言操作,例如notNull()、isTrue()、hasText()等。这些方法主要用于验证方法参数或对象状态是否满足预期条件,如果不满足,则会抛出IllegalArgumentException或IllegalStateException等运行时异常。
常用的Assert方法源码如下:
//判断传入的表达式是否为true,如果为false,则抛出`IllegalArgumentException`异常,并使用指定的错误信息
public static void isTrue(boolean expression, String message) {if (!expression) {throw new IllegalArgumentException(message);}
}//判断传入的对象是否为null,如果为null,则抛出`IllegalArgumentException`异常,并使用指定的错误信息
public static void isNull(@Nullable Object object, String message) {if (object != null) {throw new IllegalArgumentException(message);}
}
org.springframework.util.Assert类中提供的方法可以帮助我们在编码过程中进行快速的参数校验,避免使用繁琐的if语句或手动抛出异常。同时,这些方法也提供了可自定义的错误信息,有助于更好地理解校验失败的原因。
什么是异常?
异常(Exception)是程序运行时出现的错误或异常情况,它会打断程序正常的执行流程,并且可能导致程序崩溃或产生不可预期的结果。在Java中,异常通常被表示为一个继承自Throwable类的对象,例如RuntimeException、IllegalArgumentException等。
而自定义异常是指开发人员基于Java中的Exception或其子类,定义自己的异常类。通常情况下,自定义异常类用于表示特定的异常情况,以便更好地对程序的异常情况进行分类处理和管理。自定义异常类可以包含自己的属性和方法,以提供更详细的异常信息和处理方式。
需要自定义异常的原因有以下几点:
-
更细粒度的异常控制:Java标准库中的异常类型比较全面,但是在实际应用中,我们可能需要更具体的异常类型来描述某种特定场景下的异常情况。例如,我们可以自定义一个PayErrorException来表示支付异常,这样可以更好地区分不同类型的异常情况,并进行不同的处理。
-
信息更丰富:Java标准库中的异常类型通常只包含错误信息,如果需要传递更多的相关信息,就需要自定义异常类。例如,我们可以在自定义异常类中添加一些额外的属性,如异常码、请求参数等,以便更好地记录和跟踪异常信息。
-
更友好的异常提示:Java标准库中的异常信息通常比较晦涩难懂,如果需要更加友好和易于理解的提示信息,就需要自定义异常类。通过自定义异常类,开发人员可以提供更加直观和易懂的异常提示信息,以便用户或其他开发人员更好地理解异常情况。
在实际业务中,我们往往需要设置一个全局的异常处理器对异常进行统一的处理和管理,并返回相应的错误信息,确保应用程序的稳定性和可靠性。
基于断言实现的异常处理机制
创建自定义异常类
首先,需要创建一个自定义的异常类,继承自RuntimeException或其子类:
/*** 自定义通用异常类*/
public class CommonException extends RuntimeException {/*** 无参构造方法*/public CommonException() {}/*** 构造方法,传入异常信息* @param message 异常信息*/public CommonException(String message) {super(message);}/*** 构造方法,传入异常信息和原始异常对象* @param message 异常信息* @param cause 原始异常对象*/public CommonException(String message, Throwable cause) {super(message, cause);}/*** 构造方法,传入原始异常对象* @param cause 原始异常对象*/public CommonException(Throwable cause) {super(cause);}
}
在自定义异常类CommonException中我们提供了几个不同的构造方法,方便在不同场景下创建异常对象。每个构造方法都调用了父类的构造方法super,以便初始化异常对象。
创建全局异常处理器
我们还需要创建一个全局异常处理器GlobalExceptionHandler,用于统一处理我们抛出的自定义异常类:
/*** 全局异常处理器*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {/*** 处理CommonException异常* @param e 异常对象* @return 异常信息*/@ExceptionHandler(CommonException.class)public String handleCommonException(CommonException e) {log.error("错误信息:{}", e.getMessage());return e.getMessage();}
}
在全局异常处理器GlobalExceptionHandler类上我们使用了@RestControllerAdvice注解标识该类为全局异常处理器。在该类中,定义了一个方法handleCommonException,用于处理异常捕获后的逻辑,在方法上添加了@ExceptionHandler()注解表示该方法处理指定自定义异常CommonException。
创建自定义断言类
对于断言类,我们可以模仿org.springframework.util.Assert类,借鉴其中的方法,自定义一个抽象类MyAssert:
/*** 断言类*/
public abstract class MyAssert {/*** 判断对象是否为空,如果不为空则抛出CommonException异常** @param object 要进行判断的对象*/public void assertIsNull(@Nullable Object object) {// 如果对象不为空,则抛出CommonException异常,并将当前对象序列化为JSON字符串作为异常信息if (object != null) {throw new CommonException(JSON.toJSONString(this));}}}
如上,我们创建了一个assertIsNull方法,参数object用于接收要进行判断的对象,如果object为空,则抛出CommonException异常,并将当前对象序列化为JSON字符串作为异常信息。
创建响应码类
创建自定义的响应码类,同时继承断言类MyAssert,这样我们可以通过响应码直接调用断言类中的方法进行判断:
/*** 响应码类,继承自断言类MyAssert*/
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ResCode extends MyAssert {/*** 响应码*/private int code;/*** 响应消息*/private String message;}
上述代码中,使用了Lombok库的注解来简化代码编写。具体注解的含义如下:
@Getter: 自动生成属性的getter方法。@NoArgsConstructor: 自动生成无参构造方法。@AllArgsConstructor: 自动生成包含所有参数的构造方法。
创建工具类
ResCodeUtils工具类用于调用响应码进行校验,抛出自定义异常并返回指定错误信息:
/*** 响应码工具类,继承自响应码类ResCode*/
public class ResCodeUtils extends ResCode {/*** 响应码naa,表示错误*/public static ResCode naa = new ResCode(300, "错误");/*** 响应码naa1,表示naa1错误*/public static ResCode naa1 = new ResCode(4044, "naa1错误");}
在ResCodeUtils类中提供了两个静态属性naa和naa1,分别表示响应码为300和4044的错误类型,方便通过类名.的方式直接调用。
测试效果
-
编写
TestController类,添加@RestController注解表明该类是一个控制器类,用于处理HTTP请求并返回响应:@RestController public class TestController {@RequestMapping("/send1")public String send1() {ResCodeUtils.naa.assertIsNull(null);return "success";}@RequestMapping("/send2")public String send2() {ResCodeUtils.naa1.assertIsNull(new ResCode());return "success";}}在
TestController类中,定义了两个请求处理方法send1()和send2()。这两个方法使用了@RequestMapping注解来指定它们对应的URL路径。-
send1()方法中调用了ResCodeUtils.naa.assertIsNull(null),这表示对naa响应码进行断言,判断传入的参数是否为null。如果参数为null,断言通过,否则会抛出异常。 -
send2()方法中调用了ResCodeUtils.naa1.assertIsNull(new ResCode()),这表示对naa1响应码进行断言,判断传入的参数是否为null。由于参数new ResCode()不为null,所以这里会抛出异常。
无论是
send1()还是send2()方法,最终都会返回字符串"success"作为处理结果。 -
-
启动项目,使用 ApiFox 访问对应接口。
-
访问
send1(),由于参数为null,断言通过,返回字符串"success":
-
访问
send2(),由于参数为new ResCode(),不为null,断言未通过,抛出自定义异常之后被全局异常处理器GlobalExceptionHandler捕获,返回对应错误信息:
同时,可以在控制台看到打印的日志信息

-
本文到此结束,感谢您的阅读,希望对您有所帮助!!!
相关文章:
Spring Boot 使用断言抛出自定义异常,优化异常处理机制
文章目录 什么是断言?什么是异常?基于断言实现的异常处理机制创建自定义异常类创建全局异常处理器创建自定义断言类创建响应码类创建工具类测试效果 什么是断言? 实际上,断言(Assertion)是在Java 1.4 版本…...
vue基于ElementUI/Plus自定义的一些组件
vue3-my-ElementPlus 源码请到GitHub下载使用MyTable、MySelect、MyPagination 置顶|Top | 使用案例: 1.0 定义表格数据(测试使用) data() {return {tableData: [],value:[],valueList: [],}; },// 构造表格测试数据// 1 第一行…...
leetcode刷题日记:69.sqrt(x)
给出一个非负的整数x,返回x的平方根向下取整的结果,这个被返回的数也应该是一个非负的值。 对我们的要求是不能使用任何内置的指数函数与操作,官方还给了我们例子: 在C种不能使用pow(x, 0.5) 在python不能使用 x**0.5 既然官方已经…...
[尚硅谷React笔记]——第9章 ReactRouter6
目录: 课程说明一级路由重定向NavLink高亮useRoutes路由表嵌套路由路由的params参数路由的search参数路由的state参数编程式路由导航useRouterContextuseNavigationTypeuseOutletuseResolvedPath()总结项目地址 1.课程说明 概述 React Router以三个不同的包发布…...
强大的pdf编辑软件:Acrobat Pro DC 2023中文
Acrobat Pro DC 2023是一款强大的PDF编辑和管理软件,它提供了广泛的功能,使用户能够轻松创建、编辑、转换和共享PDF文档。通过直观的界面和先进的工具,用户可以快速进行文本编辑、图像调整、页面管理等操作,同时支持OCR技术&#…...
玩一下Spring Boot
文章目录 1 开发环境1.1 JDK1.2 IntelliJ IDEA2 Spring Boot2.1 创建项目2.2 创建模板页面2.3 创建控制器2.4 启动项目2.5 访问页面1 开发环境 1.1 JDK 安装JDK21 配置环境变量 在命令行查看JDK版本 玩一玩jshell...
一个高性能类型安全的.NET枚举实用开源库
从零构建.Net前后端分离项目 枚举应该是我们编程中,必不可少的了,今天推荐一个.NET枚举实用开源库,它提供许多方便的扩展方法,方便开发者使用开发。 01 项目简介 Enums.NET是一个.NET枚举实用程序库,专注于为枚举提…...
c#字符串格式化
字符串格式化是一种将变量的值插入到字符串中的方法。它允许我们创建动态的字符串,其中包含变量的值。 string.Format 通过在字符串中使用占位符{0},{1}等,我们可以指定要插入的变量的位置。然后,通过在string.Format方法的参数…...
AMD老电脑超频及性能提升方案及实施
收拾电子元件的时候找到了若干古董的CPU 其中有一个X3 440 是原来同学主板烧了之后给我的,我从网上配了AM2 昂达主板,然后又买了AMD兼容内存,组成了win7 64位电脑,用起来非常不错,我把硬件配置和升级过程说明下&#x…...
Github 自动化部署到GitHub Pages
1.准备工作 新建仓库 新建项目 配置 vite.config.ts base: ./,部署应用包时的基本URL,例:vue-cli 5.x 配置 publicPath 推送到远程仓库 2.配置 GitHub Token 点击 Settings -> Actions -> General 找到 Workflow permissions,选中第…...
Golang 串口通信
简介 串口通信是一种常见的硬件通信方式,用于在计算机和外部设备之间传输数据。Golang(Go语言)作为一种高效、可靠的编程语言,提供了丰富的库和工具用于串口通信。本文将介绍如何使用Golang进行串口通信,包括串口配置…...
项目管理之如何识别并应对项目风险
项目风险管理是项目管理中不可忽视的环节,如何识别并应对项目的风险对于项目的成功实施至关重要。本文将介绍风险管理的流程、风险分解结构、定性及定量风险评估方法,以及消极和积极的风险应对策略,旨在帮助读者更好地理解和应对项目风险。 …...
vue封装独立组件:实现手写签名功能
目录 第一章 效果展示 第二章 准备工作 2.1 使用的工具vue-sign 2.1.1 安装 2.1.2 了解 2.1.3 参数说明 第三章 源代码 第一章 效果展示 第二章 准备工作 2.1 使用的工具vue-esign 2.1.1 安装 npm install vue-esign --save 2.1.2 了解 兼容pc端和移动端有对应的参…...
图及谱聚类商圈聚类中的应用
背景 在O2O业务场景中,有商圈的概念,商圈是业务运营的单元,有对应的商户BD负责人以及配送运力负责任。这些商圈通常是一定地理围栏构成的区域,区域内包括商户和用户,商圈和商圈之间就通常以道路、河流等围栏进行分隔。…...
npx 和 npm 区别
文章目录 背景作用执行流程 背景 解决 npm 之前的执行包中的命令行需要先下载的问题,如果有多个不同版本的包就需要下载多次比如已经装了全局的 webpack 1.x 版本并且还要继续使用,还需要装个 webpack 4.x 使用的其相应功能,这个时候可以不装在全局&…...
HTML_案例1_注册页面
用纯html页面,不用css画一个注册页面。 最终效果如下: html页面代码如下: <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>注册页面</title> </head>…...
Adobe After Effects 2024(Ae2024)在新版本中的升级有哪些?
After Effects 2024是Adobe公司推出的一款视频处理软件,它适用于从事设计和视频特技的机构,包括电视台、动画制作公司、个人后期制作工作室以及多媒体工作室。通过After Effects,用户可以高效且精确地创建无数种引人注目的动态图形和震撼人心…...
超越 GLIP! | RegionSpot: 识别一切区域,多模态融合的开放世界物体识别新方法
本文的主题是多模态融合和图文理解,文中提出了一种名为RegionSpot的新颖区域识别架构,旨在解决计算机视觉中的一个关键问题:理解无约束图像中的各个区域或patch的语义。这在开放世界目标检测等领域是一个具有挑战性的任务。 关于这一块&…...
webgoat-(A1)injection
SQL Injection (intro) SQL 命令主要分为三类: 数据操作语言 (DML)DML 语句可用于请求记录 (SELECT)、添加记录 (INSERT)、删除记录 (DELETE) 和修改现有记录 ÿ…...
51单片机-中断
文章目录 前言 前言 #include <reg52.h> #include <intrins.h>sbit key_s2P3^0; sbit flagP3^7;void delay(unsigned int z){unsigned int x,y;for(xz;x>0;x--)for(y114;y>0;y--); }void int_init(){EA1;EX11;IT11;}void main(){int_init();while(1){if (key…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
【网络】每天掌握一个Linux命令 - iftop
在Linux系统中,iftop是网络管理的得力助手,能实时监控网络流量、连接情况等,帮助排查网络异常。接下来从多方面详细介绍它。 目录 【网络】每天掌握一个Linux命令 - iftop工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
Auto-Coder使用GPT-4o完成:在用TabPFN这个模型构建一个预测未来3天涨跌的分类任务
通过akshare库,获取股票数据,并生成TabPFN这个模型 可以识别、处理的格式,写一个完整的预处理示例,并构建一个预测未来 3 天股价涨跌的分类任务 用TabPFN这个模型构建一个预测未来 3 天股价涨跌的分类任务,进行预测并输…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
JAVA后端开发——多租户
数据隔离是多租户系统中的核心概念,确保一个租户(在这个系统中可能是一个公司或一个独立的客户)的数据对其他租户是不可见的。在 RuoYi 框架(您当前项目所使用的基础框架)中,这通常是通过在数据表中增加一个…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...
