08-学成在线项目中统一异常处理的规范
项目中的异常处理
规范异常类型
在Service类的业务方法中有很多的参数合法性校验,当请求参数不合法的时候会抛出异常,但此时异常信息只会在控制台输出,前端界面并不会提示用户
实际开发中前端和后端需要做一些约定: 一般将错误提示信息统一以json格式返回给前端,以HTTP状态码决定当前请求是否出错(非200为操作异常)
{"timestamp":"2023-02-02T14:42:36.820+00:00",// 添加课程时设置一个负数的课程价格会报500异常"status":500,"error":"Internal Server Error","message":"","path":"/content/course"
}
为了统一处理异常信息,我们需要在业务方法中自定义并规范项目中抛出的异常类型,这样可以便于统一去捕获这一类或几类的异常
- 对于业务方法中抛出的
非项目自定义的异常类型即未知异常,则统一向用户提示指定的错误信息如执行过程异常请重试的
规范了异常类型, 我们还需要去捕获异常信息,使用try/catch方式去捕获代码比较臃肿,可以统一由SpringMVC提供的控制器增强类去完成异常的捕获

异常处理(base工程)
第一步: 添加依赖,在base基础工程实现统一异常处理,由于各模块依赖了base基础工程所以都可以使用异常处理
<dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId>
</dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
第二步: 定义一个枚举类CommonError,枚举一些通用的异常信息对象
package com.xuecheng.base.execption;
/**
* @description 通用错误信息
*/
public enum CommonError {UNKOWN_ERROR("执行过程异常,请重试"),PARAS_ERROR("非法参数"),OBJECT_NULL("对象为空"),QUERY_NULL("查询结果为空"),REQUEST_NULL("请求参数为空");private String errMessage;public String getErrMessage() {return errMessage;}CommonError(String errMessage) {this.errMessage = errMessage;}
}
第三步: 自定义项目的异常类型XueChengPlusException
package com.xuecheng.base.execption;
/**
* @description 学成在线项目异常类
*/
public class XueChengPlusException extends RuntimeException {private String errMessage;public String getErrMessage() {return 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);}
}
第四步: 自定义响应异常信息的模型类
package com.xuecheng.base.execption;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RestErrorResponse implements Serializable {private String errMessage;
}
第五步: 定义全局异常处理器去捕获异常信息同时记录异常日志, 将异常信息封装到异常信息的模型类并响应给用户,实现微服务端全局异常处理
@ControllerAdvice或@RestControllerAdvice)(类上): 将当前类标识为异常处理的组件@ExceptionHandler(方法或类上): 用于表明方法处理的异常类型,可以指定一个或多个@ResponseStatus(方法或类上): 标记捕获异常的方法或类指定发生异常时异常处理器向前端响应的状态码和原因
package com.xuecheng.base.execption;
/**
* @description 全局异常处理器
*/
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {@ResponseBody@ExceptionHandler(XueChengPlusException.class)// 处理项目自定义异常类型@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 该异常枚举对象的错误码为500public RestErrorResponse customException(XueChengPlusException exception) {log.error("系统异常:{}", exception.getErrMessage());return new RestErrorResponse(exception.getErrMessage());}@ResponseBody@ExceptionHandler(Exception.class)// 未知类型的异常@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)// 该异常枚举对象的错误码为500public RestErrorResponse exception(Exception exception) {log.error("系统异常:{}", exception.getMessage());return new RestErrorResponse(exception.getMessage());}
}
异常处理测试(api工程)
第一步: 在内容管理服务的api工程中添加base工程的依赖
<dependency><groupId>com.xuecheng</groupId><artifactId>xuecheng-plus-base</artifactId><version>0.0.1-SNAPSHOT</version>
</dependency>
第二步: 当业务方法中出现异常时抛出项目自定义的异常类型,这里以新增课程的业务方法为例进行代码修改
@Override
public CourseBaseInfoDto createCourseBase(Long companyId,AddCourseDto dto) {//合法性校验if (StringUtils.isBlank(dto.getName())) {throw new XueChengPlusException("课程名称为空");}if (StringUtils.isBlank(dto.getMt())) {throw new XueChengPlusException("课程分类为空");}if (StringUtils.isBlank(dto.getSt())) {throw new XueChengPlusException("课程分类为空");}if (StringUtils.isBlank(dto.getGrade())) {throw new XueChengPlusException("课程等级为空");}if (StringUtils.isBlank(dto.getTeachmode())) {throw new XueChengPlusException("教育模式为空");}if (StringUtils.isBlank(dto.getUsers())) {throw new XueChengPlusException("适应人群");} if (StringUtils.isBlank(dto.getCharge())) {throw new XueChengPlusException("收费规则为空");}if(charge.equals("201001")){if(courseMarketNew.getPrice() ==null || courseMarketNew.getPrice().floatValue()<=0){throw new XueChengPlusException("课程的价格不能为空并且必须大于0");}}
}
第三步: 使用HTTP Client进行测试,故意将收费课程价格设置为负数, 查看捕获到的响应信息

POST http://localhost:53040/content/courseHTTP/1.1 500
Content-Type: application/json
Transfer-Encoding: chunked
Date: Fri, 03 Feb 2023 02:32:20 GMT
Connection: close{"errMessage": "课程设置了收费,价格不能为空,且必须大于0"
}
相关文章:
08-学成在线项目中统一异常处理的规范
项目中的异常处理 规范异常类型 在Service类的业务方法中有很多的参数合法性校验,当请求参数不合法的时候会抛出异常,但此时异常信息只会在控制台输出,前端界面并不会提示用户 实际开发中前端和后端需要做一些约定: 一般将错误提示信息统一以json格式返回给前端,以HTTP状态码…...
解析生效探测方法
linux dig命令 1.最常用的查询命令 dig baidu.com2 . 根据记录类型进行查询,比如MX,CNAME,NS,PTR等,只需将类型加在命令后面即可。 dig a.shifen.com ns3 . 指定域名DNS服务器测试解析是否生效的命令,以…...
【科技素养】蓝桥杯STEMA 科技素养组模拟练习试卷11
单选题 1、在阅读文章和接受信息时注意区分事实和观点十分重要。事实(或称为命题)不同于观点的一个主要特征是 A、可以被证实或证伪 B、是准确无误的 C、是正式的表达 D、表达了个人看法 答案:A 2、现代意义的知识产权是在多数国家都受…...
视频集中存储/磁盘阵列EasyCVR平台黑名单异常解决步骤是什么?
视频云存储/安防监控EasyCVR视频汇聚平台基于云边端智能协同,支持海量视频的轻量化接入与汇聚、转码与处理、全网智能分发、视频集中存储等。音视频流媒体视频平台EasyCVR拓展性强,视频能力丰富,具体可实现视频监控直播、视频轮播、视频录像、…...
Spring Boot + MyBatis-Plus实现数据库读写分离
文章目录 1. 引言2. MyBatis-Plus简介3. 准备工作4. 配置数据源5. 配置MyBatis-Plus6. 创建实体类和Mapper接口7. 编写Service8. 控制器层9. 测试10. 数据库读写分离的原理11. 拓展11.1. 动态数据源11.2. 多数据源事务管理11.3. 多租户支持 12. 总结 🎉Spring Boot …...
数据同步异常处理,数据同步重试机制(Java)
一、应用场景 在数据同步时,偶尔会出现代码异常之外的问题。例如网络异常、服务器断电… 如果在以上异常片段中,原始数据库新增了一批数据,同步数据库则会丢失这部分数据 二、实现思路 为了解决以上问题,保证原始数据库操作的每…...
STM32F407-14.3.5-01捕获_比较通道
捕获/比较通道 每一个捕获/比较通道都是围绕着一个捕获/比较寄存器(包含影子寄存器) 包括: 捕获的输入部分(数字滤波、多路复用和预分频器), 输出部分(比较器和输出控制)。 中文参考手册中框图分成了三大模块, 把框图合并成了一个整体,以便更好的理解捕获输…...
【Python 训练营】N_12 打印菱形图案
题目 打印菱形图案 分析 先把图形分成两部分来看待,前四行一个规律,后三行一个规律,利用双重for循环,第一层控制行,第二层控制列。 答案 # 方法一 for i in range(4):block **(2*i1)print({:^7}.format(block))…...
risc-v异常处理
异常与中断的关系 中断和异常都为异常,分为: 同步异常:IO,illegal, page fault,miss_aligh 等来自处理器内部的发生的异常。异步异常(中断):鼠标,键盘,Time…...
SQL注入-数据库基础/SQL语法
目录 一,数据库概述 1.1 数据库 1.2 了解 ACID 理论 1.3 识别数据库 二,SQL 语法基础 三,SQL语句实例 3.1 SQL基础语句 3.2 SQL高级语句 四,基于SQL注入理解语法/函数 4.1 语法 4.2 函数 五,目录数据库info…...
Blazor Select 实现点击一次选项触发一次后台事件
Blazor的官方案例中,Select组件只有两个事件 1、OnSelectedItemChanged 每次选项的时候改变触发,如果你点击同一个选项是不会触发后台的方法的 2、OnBeforeSelectedItemChange 我们可以用这个事件实现每次点击同一个选项都可以触发后台事件 需要注意下最…...
只会在终端使用Python运行代码?这些高级用法了解了解
大部分同学在终端使用Python可能只是简单的执行代码,但其实结合一些Python内置模块或第三方库可以实现更高级且便捷的用法,一起看看吧 插播,更多文字总结指南实用工具科技前沿动态第一时间更新在公粽号【啥都会一点的研究生】 代码Benchmar…...
图论 2023.11.27
Kruskal定义不同的优先级 P3623 [APIO2008] 免费道路 给定一个无向图,其中一些边是0,其他边为1 两个不同的点之间都应该一条且仅由一条边连接 并保持刚好K条0,求是否有解决方案 n<2e4,m<1e5 Kruskal定义不同的优先级 思路:…...
蓝桥杯day02——Fizz Buzz
1、题目 给你一个整数 n ,找出从 1 到 n 各个整数的 Fizz Buzz 表示,并用字符串数组 answer(下标从 1 开始)返回结果,其中: answer[i] "FizzBuzz" 如果 i 同时是 3 和 5 的倍数。answer[i] &…...
socket 一个完整的不错的示例
从客户端向服务器端发送信息时,在服务器端有打印显示; 检测环境常用,备份一下 0,公共头文件代码 //config.h#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #inc…...
第10关:基数排序
任务要求参考答案问答98 任务描述相关知识 基数排序算法编程要求测试说明 任务描述 本关任务:实现基数排序算法,并将乱序数列变成升序。 相关知识 为了完成本关任务,你需要掌握:1.基数排序算法。 基数排序算法 基数排序是按…...
torch::和at:: factory function的差別
torch::和at:: factory function的差別 前言torch::autograd::THPVariable_randtorch::rand_symintat::rand_symintdemotorch命名空間at命名空間 前言 >>> import torch >>> a torch.rand(3, 4) >>> a.requires_grad False >>> a torch…...
与珎同行录-开篇-231129
与珎同行录-开篇 珎就是对陪伴并帮助我写代码的AI的昵称 能不能读懂这个绕口令问题呢? 连续的椎体的相邻椎体质心的相邻质心的质心作为当前质心所在的椎体的质心, 该质心的方向代表该椎体的上下方向 如何代码实现呢? 还是没看懂…好吧最终的算法是:...
linux logrotate日志轮询设置案例一
1.编辑/etc/logrotate.conf文件,添加如下配置,并保存 /var/log/ztj.log {missingokhourlycreate 644 root rootsharedscriptspostrotateif [ -f /var/run/syslogd.pid ];then/bin/kill -HUP $(/bin/cat /var/run/syslogd.pid) >/dev/null 2>&…...
Android 12.0 禁用adb reboot recovery命令实现正常重启功能
1.前言 在12.0的系统rom定制化开发中,在定制recovery模块的时候,由于产品开发需要要求禁用recovery的相关功能,比如在通过adb命令的 adb reboot recovery的方式进入recovery也需要实现禁用,所以就需要了解相关进入recovery流程来禁用该功能 2.禁用adb reboot recovery命令…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
摘要 本论文旨在设计并实现基于 SpringBoot 和 uniapp 的 Champion 俱乐部微信小程序,以满足俱乐部线上活动推广、会员管理、社交互动等需求。通过 SpringBoot 搭建后端服务,提供稳定高效的数据处理与业务逻辑支持;利用 uniapp 实现跨平台前…...
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
重启Eureka集群中的节点,对已经注册的服务有什么影响
先看答案,如果正确地操作,重启Eureka集群中的节点,对已经注册的服务影响非常小,甚至可以做到无感知。 但如果操作不当,可能会引发短暂的服务发现问题。 下面我们从Eureka的核心工作原理来详细分析这个问题。 Eureka的…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
