Spring Boot3自定义异常及全局异常捕获

⛰️个人主页: 蒾酒
🔥系列专栏:《spring boot实战》
🌊山高路远,行路漫漫,终有归途。
目录
前置条件
目的
主要步骤
定义自定义异常类
创建全局异常处理器
手动抛出自定义异常
前置条件
已经初始化好一个spring boot项目且版本为3X,项目可正常启动。
作者版本为3.2.2
初始化教程:
新版idea(2023)创建spring boot3项目-CSDN博客
https://blog.csdn.net/qq_62262918/article/details/135785412?spm=1001.2014.3001.5501
目的
Spring Boot应用程序开发中,会遇到各种异常有可预知的也有不可预知的,我们很少会每个过程做单独异常处理,通常会将各种类型的异常处理过程解耦出来,保证业务逻辑单一、相关异常处理单一。
通常将异常进行处理,封装一下对应错误信息返回友好信息。避免把异常直接给前端、用户。
反例:异常直接返回(不友好)

正例:处理后返回提示信息(友好)

主要步骤
定义自定义异常类
下面我们定义几个自定义异常
1.账号不存在异常
import com.mijiu.commom.enumerate.ResultEnum;
import lombok.Getter;/*** 账户不存在异常** @author mijiupro*/
@Getter
public class AccountNotFoundException extends RuntimeException {private final ResultEnum resultEnum;public AccountNotFoundException(ResultEnum resultEnum) {this.resultEnum = resultEnum;}
}
2.密码错误异常
import com.mijiu.commom.enumerate.ResultEnum;
import lombok.Getter;/*** 密码错误异常** @author mijiupro*/
@Getter
public class PasswordErrorException extends RuntimeException {private final ResultEnum resultEnum;public PasswordErrorException(ResultEnum resultEnum) {this.resultEnum = resultEnum;}}
3. 令牌过期异常
import com.mijiu.commom.enumerate.ResultEnum;
import lombok.Getter;/*** 令牌过期异常** @author mijiupro*/
@Getter
public class TokenOverdueException extends RuntimeException {private final ResultEnum resultEnum;public TokenOverdueException(ResultEnum resultEnum) {this.resultEnum = resultEnum;}
}
对于各种异常的错误码以及提示内容通常使用枚举类如下:
import lombok.Getter;/*** @author mijiupro*/
@Getter
public enum ResultEnum {/* 成功状态码 */SUCCESS(1, "操作成功!"),/* 错误状态码 */FAIL(0, "操作失败!"),/* 参数错误:10001-19999 */PARAM_IS_INVALID(10001, "参数无效"),PARAM_IS_BLANK(10002, "参数为空"),PARAM_TYPE_BIND_ERROR(10003, "参数格式错误"),PARAM_NOT_COMPLETE(10004, "参数缺失"),/* 用户错误:20001-29999*/USER_NOT_LOGGED_IN(20001, "用户未登录,请先登录"),USER_LOGIN_ERROR(20002, "账号不存在或密码错误"),USER_ACCOUNT_FORBIDDEN(20003, "账号已被禁用"),USER_NOT_EXIST(20004, "用户不存在"),USER_HAS_EXISTED(20005, "用户已存在"),/* 系统错误:40001-49999 */FILE_MAX_SIZE_OVERFLOW(40003, "上传尺寸过大"),FILE_ACCEPT_NOT_SUPPORT(40004, "上传文件格式不支持"),/* 数据错误:50001-599999 */RESULT_DATA_NONE(50001, "数据未找到"),DATA_IS_WRONG(50002, "数据有误"),DATA_ALREADY_EXISTED(50003, "数据已存在"),AUTH_CODE_ERROR(50004, "验证码错误"),/* 权限错误:70001-79999 */PERMISSION_UNAUTHENTICATED(70001, "此操作需要登陆系统!"),PERMISSION_UNAUTHORIZED(70002, "权限不足,无权操作!"),PERMISSION_EXPIRE(70003, "登录状态过期!"),PERMISSION_TOKEN_EXPIRED(70004, "token已过期"),PERMISSION_LIMIT(70005, "访问次数受限制"),PERMISSION_TOKEN_INVALID(70006, "无效token"),PERMISSION_SIGNATURE_ERROR(70007, "签名失败");// 状态码int code;// 提示信息String message;ResultEnum(int code, String message) {this.code = code;this.message = message;}public int code() {return code;}public String message() {return message;}public void setCode(int code) {this.code = code;}public void setMessage(String message) {this.message = message;}
}
创建全局异常处理器
需要创建一个全局异常处理器类,用于捕获和处理所有的异常。可以使用@ControllerAdvice 或者@RestControllerAdvice注解将该类标记为全局异常处理器,并使用@ExceptionHandler 注解定义具体的异常处理方法。例如,创建一个名为 GlobalExceptionHandler 的全局异常处理器类:
import com.mijiu.commom.exception.AccountNotFoundException;
import com.mijiu.commom.exception.PasswordErrorException;
import com.mijiu.commom.exception.TokenOverdueException;
import com.mijiu.commom.result.Result;
import com.mijiu.commom.enumerate.ResultEnum;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;/*** @author mijiupro*/
@RestControllerAdvice(basePackages = "com.mijiu.controller")
@ResponseBody
@Slf4j
public class GlobalExceptionHandler {// 账号不存在异常@ExceptionHandler(AccountNotFoundException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public Result<String> handleAccountNotFoundException(AccountNotFoundException ex) {return Result.error(ex.getResultEnum());}// 密码错误异常@ExceptionHandler(PasswordErrorException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public Result<String> handlePasswordErrorException(PasswordErrorException ex) {return Result.error(ex.getResultEnum());}// 登录状态过期异常@ExceptionHandler(TokenOverdueException.class)@ResponseStatus(HttpStatus.UNAUTHORIZED)public Result<?> handleTokenOverdueException(TokenOverdueException ex){return Result.error(ex.getResultEnum());}/**** 通用异常处理*/@ExceptionHandler(Exception.class)public Result<String> exceptionHandler(Exception ex) {log.error(ex.getMessage());return Result.error(ResultEnum.FAIL);}
}
对于不可预知的异常通常直接捕获所有异常父类Exception异常即可

这段代码会触发ArithmeticException ,类似这种的不可预知异常会有很多,它们都继承自Exception所以全局拦截Exception进行处理即可。


对于异常的处理返回的信息通常用统一格式封装:
import com.mijiu.commom.enumerate.ResultEnum;
import lombok.Data;/*** @author mijiupro*/@Data
public class Result<T> {// 操作代码Integer code;// 提示信息String message;// 结果数据T data;public Result(ResultEnum resultCode) {this.code = resultCode.code();this.message = resultCode.message();}public Result(ResultEnum resultCode, T data) {this.code = resultCode.code();this.message = resultCode.message();this.data = data;}public Result(String message) {this.message = message;}//成功返回封装-无数据public static Result<String> success() {return new Result<String>(ResultEnum.SUCCESS);}//成功返回封装-带数据public static <T> Result<T> success(T data) {return new Result<T>(ResultEnum.SUCCESS, data);}//失败返回封装-使用默认提示信息public static Result<String> error() {return new Result<String>(ResultEnum.FAIL);}//失败返回封装-使用返回结果枚举提示信息public static Result<String> error(ResultEnum resultCode) {return new Result<String>(resultCode);}//失败返回封装-使用自定义提示信息public static Result<String> error(String message) {return new Result<String>(message);}
}
手动抛出自定义异常
在业务代码中抛出对应业务自定义异常:
有参构造传递错误枚举信息(状态码+错误内容),全局异常捕获并从自定义异常类拿到相关返回信息统一封装返回。
像这样直接抛出即可


相关文章:
Spring Boot3自定义异常及全局异常捕获
⛰️个人主页: 蒾酒 🔥系列专栏:《spring boot实战》 🌊山高路远,行路漫漫,终有归途。 目录 前置条件 目的 主要步骤 定义自定义异常类 创建全局异常处理器 手动抛出自定义异常 前置条件 已经初始化好一个…...
【python】网络爬虫与信息提取--Beautiful Soup库
Beautiful Soup网站:https://www.crummy.com/software/BeautifulSoup/ 作用:它能够对HTML.xml格式进行解析,并且提取其中的相关信息。它可以对我们提供的任何格式进行相关的爬取,并且可以进行树形解析。 使用原理:它能…...
谷歌浏览器,如何将常用打开的网站创建快捷方式到电脑桌面?
打开谷歌浏览器,打开想要创建的快捷方式的网页 点击浏览器右上角的三个点: 点击选择【更多工具】 选择【创建快捷方式】 然后,在浏览器上方会弹出一个框,让命名此创建的快捷方式的名称 命名好之后,再点击【创…...
产品经理面试题解析:业务架构是通往成功的关键吗?
大家好,我是小米!今天我要和大家聊的是产品经理面试中的一个热门话题:“业务架构”!相信不少小伙伴在准备面试的时候都会遇到这个问题,究竟什么是业务架构?它又与产品经理的工作有着怎样的关系呢࿱…...
【蓝桥杯】灭鼠先锋
一.题目描述 二.解题思路 博弈论: 只能转移到必胜态的,均为必败态。 可以转移到必败态的,均为必胜肽。 最优的策略是,下一步一定是必败态。 #include<iostream> #include<map> using namespace std;map<string,bo…...
2024年华为OD机试真题-求字符串中所有整数的最小和-Python-OD统一考试(C卷)
题目描述: 输入字符串s,输出s中包含所有整数的最小和 说明 1. 字符串s,只包含 a-z A-Z +- ; 2. 合法的整数包括 1) 正整数 一个或者多个0-9组成,如 0 2 3 002 102 2)负整数 负号 - 开头,数字部分由一个或者多个0-9组成,如 -0 -012 -23 -00023 输入描述: 包含…...
数据分析基础之《pandas(7)—高级处理2》
四、合并 如果数据由多张表组成,那么有时候需要将不同的内容合并在一起分析 1、先回忆下numpy中如何合并 水平拼接 np.hstack() 竖直拼接 np.vstack() 两个都能实现 np.concatenate((a, b), axis) 2、pd.concat([data1, data2], axis1) 按照行或者列…...
fluent脱硝SCR相对标准偏差、氨氮比、截面速度计算
# -*- coding: utf-8 -*- """ Created on Wed Sep 20 20:40:30 2023 联系QQ:3123575367,专业SCR脱硝仿真。 该程序用来处理fluent通过export-solution-ASCII-Space导出的数据,可计算标准偏差SD、相对标准偏差RSD,适用于求解平面的相对均匀…...
Codeforces Round 925 (Div. 3)(A~E)
题目暂时是AC,现在是Hack阶段,代码仅供参考。 A. Recovering a Small String 题目给出的n都可以由字母来组成,比如4可以是aab,字母里面排第一个和第二个,即1124。但是会歧义,比如aba为1214,也是…...
@RequestBody、@RequestParam、@RequestPart使用方式和使用场景
RequestBody和RequestParam和RequestPart使用方式和使用场景 1.RequestBody2.RequestParam3.RequestPart 1.RequestBody 使用此注解接收参数时,适用于请求体格式为 application/json,只能用对象接收 2.RequestParam 接收的参数是来自HTTP 请求体 或 请…...
LeetCode、1143. 最长公共子序列【中等,二维DP】
文章目录 前言LeetCode、1143. 最长公共子序列【中等,二维DP】题目链接与分类思路2022年暑假学习思路及题解二维DP解决 资料获取 前言 博主介绍:✌目前全网粉丝2W,csdn博客专家、Java领域优质创作者,博客之星、阿里云平台优质作者…...
162基于matlab的多尺度和谱峭度算法对振动信号进行降噪处理
基于matlab的多尺度和谱峭度算法对振动信号进行降噪处理,选择信号峭度最大的频段进行滤波,输出多尺度谱峭度及降噪结果。程序已调通,可直接运行。 162 matlab 信号处理 多尺度谱峭度 (xiaohongshu.com)...
Android Studio六大基本布局的概览和每个布局的关键特性以及实例分析
1. 线性布局 (LinearLayout) 描述: 线性布局是一种按指定方向(水平或垂直)排列其子视图的布局容器。通过android:orientation属性可设置为horizontal或vertical。 关键属性: android:orientation: 指定布局方向。android:layout_weight: 子视图权重,用于分配剩余空间。示…...
【go语言】一个简单HTTP服务的例子
一、Go语言安装 Go语言(又称Golang)的安装过程相对简单,下面是在不同操作系统上安装Go语言的步骤: 在Windows上安装Go语言: 访问Go语言的官方网站(golang.org)或者使用国内镜像站点࿰…...
LeetCode Python - 15.三数之和
目录 题目答案运行结果 题目 给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k ,同时还满足 nums[i] nums[j] nums[k] 0 。请 你返回所有和为 0 且不重复的三元组。 注意:答案中不可…...
C#中implicit和explicit
理解: 使用等号代替构造函数调用的效果以类似重载操作符的形式定义用于类型转换的函数前者类型转换时候直接写等号赋值语法,后者要额外加目标类型的强制转换stirng str -> object o -> int a 可以 int a (int)(str as object)转换通过编译,但没有转换逻辑所以运行会报错…...
探讨java系统中全局唯一ID实现方案
为什么需要全局唯一ID 我们这里引用美团 Leaf 的场景介绍:在复杂分布式系统中,往往需要对大量的数据和消息进行唯一标识。如在美团点评的金融、支付、餐饮、酒店、猫眼电影等产品的系统中,数据日渐增长,对数据分库分表后需要有一…...
微信小程序(四十四)鉴权组件插槽-登入检测
注释很详细,直接上代码 新增内容: 1.鉴权组件插槽的用法 2.登入检测示范 源码: app.json {"usingComponents": {"auth":"/components/auth/auth"} }app.js App({globalData:{//定义全局变量isLoad:false} })…...
【ES】--ES集成热更新自定义词库(字典)
目录 一、问题描述二、具体实施1、Tomcat实现远程扩展字典2、验证生效3、ES配置远程扩展字典4、为何不重启ES能实现热更新 一、问题描述 问题现象: 前面完成了自定义分词器词库集成到ES中。在实际项目中词库是时刻在变更的,但又不希望重启ES,对此我们应…...
能源管理师——为能源可持续发展护航
能源管理师是在能源管理领域具有专业知识和技能的专业人士,他们的工作对于实现能源的有效利用和可持续发展至关重要。 能源管理师的主要职责是协助企业或组织进行能源管理,包括能源规划、能源审计、节能措施的实施和能源绩效的评估等。他们通过对能源使…...
XML Group端口详解
在XML数据映射过程中,经常需要对数据进行分组聚合操作。例如,当处理包含多个物料明细的XML文件时,可能需要将相同物料号的明细归为一组,或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码,增加了开…...
突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...
Appium+python自动化(十六)- ADB命令
简介 Android 调试桥(adb)是多种用途的工具,该工具可以帮助你你管理设备或模拟器 的状态。 adb ( Android Debug Bridge)是一个通用命令行工具,其允许您与模拟器实例或连接的 Android 设备进行通信。它可为各种设备操作提供便利,如安装和调试…...
【WiFi帧结构】
文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成:MAC头部frame bodyFCS,其中MAC是固定格式的,frame body是可变长度。 MAC头部有frame control,duration,address1,address2,addre…...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
