java中统一异常处理,如何实现全局异常处理,@RestControllerAdvice 注解实现统一异常处理

文章目录

      • 一、粗谈统一异常处理
      • 二、细谈统一异常处理:结合统一结果返回类
        • 为什么使用统一异常处理?
        • 怎么做?如何处理?代码实现?

一、粗谈统一异常处理

先看个案例:

1、写了一个接口:

实体类如下:

@Data
public class Emp {@NotNull(message = "id 不能为 null")private Integer id;@NotNull(message = "name 不能为 null")private String name;
}

接口如下:

@RestController
public class EmpController {@PostMapping("/emp")public String createEmp(@Valid @RequestBody Emp emp) {return "ok";}
}

测试时,假如不传 id、name,会抛出 MethodArgumentNotValidException 异常。使用 BindingResult 可以处理异常信息,但 通常使用统一异常处理

① 使用 BindingResult:

@RestController
public class EmpController {@PostMapping("/emp")public Map createEmp(@Valid @RequestBody Emp emp, BindingResult result) {if (result.hasErrors()) {Map<String, String> map = new HashMap<>();// 获取校验结果,遍历获取捕获到的每个校验结果result.getFieldErrors().forEach(item -> {// 获取校验的信息String message = item.getDefaultMessage(); // 也获取message的值String field = item.getField(); //获取属性名// 存储得到的校验结果map.put(field, message);});return map;}return "ok";}
}

问题:通过上面的步骤,已经可以捕获异常、处理异常,但是每次都是在业务方法中手动处理逻辑,这样的实现,代码肯定会冗余。可以将其抽出,使用 统一异常处理,每次异常发生时,将其捕获。

② 全局统一异常处理:@RestControllerAdvice、@ExceptionHandler

@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(MethodArgumentNotValidException.class)public Map handlerValidException(MethodArgumentNotValidException e) {BindingResult result = e.getBindingResult();Map<String, String> map = new HashMap<>();// 获取校验结果,遍历获取捕获到的每个校验结果result.getFieldErrors().forEach(item ->{// 存储得到的校验结果map.put(item.getField(), item.getDefaultMessage());});return map;}
}

Controller 中不需要再用 BindingResult 去处理数据了。

二、细谈统一异常处理:结合统一结果返回类

提示:统一结果返回类,可查看这篇文章:点击查看

为什么使用统一异常处理?

使用统一结果处理时,有些异常我们可以提前预知并处理,但是一个运行时异常,我们不一定能预知并处理,这时可以使用统一异常处理,当异常发生时,触发该处理操作,从而保证程序的健壮性。

怎么做?如何处理?代码实现?
  • 使用 @ControllerAdvice 或者 @RestControllerAdvice 注解作为统一异常处理的核心。

    这两个注解都是 Spring MVC 提供的

@ControllerAdvice 和 **@RestControllerAdvice **的区别:

@RestControllerAdvice 注解包含了 @ControllerAdvice@ResponseBody 注解。类似于 @Controller@RestController 的区别。

步骤: 使用 @ControllerAdvice 或者 @RestControllerAdvice 注解标记一个 全局异常处理类。全局异常处理类内部使用 @ExceptionHandler 注解去捕获异常。

可选操作:可以自定义一个异常信息收集类,用于处理项目中的异常,并收集异常信息。

代码实现:

1、可选操作:自定义一个异常类,用于处理项目中的异常,并收集异常信息。

/*** 自定义异常类* 可以自定义 异常信息message、响应状态码 code(默认为500)*/
@Data
public class GlobalException extends RuntimeException {// 保存异常信息private String message;// 保存响应状态码(默认为500)private Integer code = HttpStatus.SC_INTERNAL_SERVER_ERROR;// 默认构造方法,根据异常信息   构建一个异常实例对象public GlobalException(String message) {super(message);this.message = message;}// 根据异常信息、响应状态码   构建一个异常实例对象public GlobalException(String message, Integer code) {super(message);this.message = message;this.code = code;}// 根据异常信息、异常对象      构建一个异常实例对象public GlobalException(String message, Throwable e) {super(message, e);this.message = message;}// 根据异常信息、响应状态码、异常对象    构建一个异常实例对象public GlobalException(String message, Integer code, Throwable e) {super(message, e);this.message = message;this.code = code;}
}

2、全局异常处理类:

  • 定义一个全局的异常处理类 GlobalExceptionHandler。使用 @RestControllerAdvice 注解标记这个类。
  • 内部使用 @ExceptionHandler 注解去捕获异常。
// 使用统一结果返回类:Result
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {// 处理 Exception 异常@ExceptionHandler(Exception.class)public Result handlerException(Exception e) {log.error(e.getMessage(), e);return Result.error().message("系统异常");}// 处理空指针异常@ExceptionHandler(NullPointerException.class)public Result handlerNullPointerException(NullPointerException e) {log.error(e.getMessage(), e);return Result.error().message("空指针异常");}// 处理自定义异常@ExceptionHandler(GlobalException.class)public Result handlerGlobalException(GlobalException e) {log.error(e.getMessage(), e);return Result.error().message(e.getMessage()).code(e.getCode());}
}

3、使用:修改某个 controller 如下所示:

@GetMapping("/test")
public Result test(Integer id) { if (id == 0) {throw new NullPointerException();}if (id == -1) {throw new GlobalException("参数异常", 400);}if (id == 1) {throw new GlobalException("未查询到结果,请确认输入是否正确");}return Result.ok().data("items", 123456).message("查询成功");
}

参数为 0 时,抛出 空指针异常。

{"success": false,"code": 500,"message": "空指针异常","data": {}
}

参数为 -1 时,抛出自定义异常并处理。

{"success": false,"code": 400,"message": "参数异常","data": {}
}

参数为 1 时,抛出自定义异常并处理。

{"success": false,"code": 500,"message": "未查询到结果,请确认输入是否正确","data": {}
}

查询成功时,正确处理并返回。

至此,文章结束!!!记得关注哦!!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/501281.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C语言程序设计——循环程序设计】枚举法换硬币(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 一、循环控制 / 跳转语句的使用 1. 循环控制语句&#xff08;for 循环&#xff09; 2. 循环控制语句&#xff08;while 循环&#xff09; 3. 跳转语句&#xff08;break 语句&#xff09; 4. 跳转语句&#xff08;continue 语句&…

【Multisim用74ls92和90做六十进制】2022-6-12

缘由Multisim如何用74ls92和90做六十进制-其他-CSDN问答 74LS92、74LS90参考

计算机的错误计算(二百)

摘要 用三个大模型计算 exp(123.456). 结果保留10位有效数字。三个大模型的输出均是错误的&#xff0c;虽然其中一个给出了正确的 Python代码。 例1. 计算 exp(123.456). 保留10位有效数字。 下面是与第一个大模型的对话。 以上为与一个大模型的对话。 下面是与另外一个大模…

自行下载foremos命令

文章目录 问题描述其他小伙伴的成功解决方案&#xff0c;但对我不适用解决思路失败告终 最终解决成功解决思路解决步骤 问题描述 在kali系统终端中输入foremost&#xff0c;显示无此命令 其他小伙伴的成功解决方案&#xff0c;但对我不适用 解决思路 正常来说使用命令 apt-g…

docker 安装influxdb

docker pull influxdb mkdir -p /root/influxdb/data docker run -d --name influxdb -p 8086:8086 -v /root/influxdb/data:/var/lib/influxdb influxdb:latest#浏览器登录&#xff1a;http://192.168.31.135:8086&#xff0c;首次登录设置用户名密码&#xff1a;admin/admin1…

Leetcode打卡:我的日程安排表II

执行结果&#xff1a;通过 题目 731 我的日程安排表II 实现一个程序来存放你的日程安排。如果要添加的时间内不会导致三重预订时&#xff0c;则可以存储这个新的日程安排。 当三个日程安排有一些时间上的交叉时&#xff08;例如三个日程安排都在同一时间内&#xff09;&#…

创龙3588——debian根文件系统制作

文章目录 build.sh debian 执行流程build.sh源码流程 30-rootfs.sh源码流程 mk-rootfs-bullseys.sh源码流程 mk-sysroot.sh源码流程 mk-image.sh源码流程 post-build.sh 大致流程系统制作步骤 build.sh debian 执行流程 build.sh 源码 run_hooks() {DIR"$1"shiftf…

拟声 0.60.0 | 拟态风格音乐播放器,支持B站音乐免费播放

「拟声」是一款音乐播放器&#xff0c;不仅支持音视频的本地播放&#xff0c;还提供了账号注册功能&#xff0c;登录后可享受自动同步歌单、歌词等。它支持播放绝大多数音频格式&#xff0c;具备固定输出采样率、独占输出、内置均衡器和音调调整等功能。同时&#xff0c;它也支…

计算机网络 (16)数字链路层的几个共同问题

一、封装成帧 封装成帧是数据链路层的一个基本问题。数据链路层把网络层交下来的数据构成帧发送到链路上&#xff0c;以及把接收到的帧中的数据取出并上交给网络层。封装成帧就是在一段数据的前后分别添加首部和尾部&#xff0c;构成了一个帧。接收端在收到物理层上交的比特流后…

Linux Shell 脚本编程基础知识篇—awk的条件判断(3)

ℹ️大家好&#xff0c;我是练小杰&#xff0c;今天周五了&#xff0c;又是一周过去了&#x1f606; 本文是有关Linux shell脚本编程的awk命令的条件语句&#xff0c;后续我会不断增加相关内容 ~~ 回顾:【awk字符串函数和内置变量】 更多Linux 相关内容请点击&#x1f449;【Li…

小程序学习07—— uniapp组件通信props和$emit和插槽语法

目录 一 父组件向子组件传递消息 1.1 props &#xff08;a&#xff09;传递静态或动态的 Prop &#xff08;b&#xff09;单向数据流 二 子组件通知父组件 2.1 $emit &#xff08;a&#xff09;定义自定义事件 &#xff08;b&#xff09;绑定自定义事件 三 插槽语法…

【深度学习进阶】基于CNN的猫狗图片分类项目

介绍 基于卷积神经网络&#xff08;CNN&#xff09;的猫狗图片分类项目是机器学习领域中的一种常见任务&#xff0c;它涉及图像处理和深度学习技术。以下是该项目的技术点和流程介绍&#xff1a; 技术点 卷积神经网络 (CNN): CNN 是一种专门用于处理具有类似网格结构的数据的…

【pytorch-lightning】架构一览

pytorch-lightning是基于pytorch的一个套壳项目&#xff0c;适配pytorch的版本同步更新速度很快。 它将训练的几个主要流程模块化&#xff0c;减少重复工作&#xff0c;同时让支持分布式训练&#xff0c;不同平台的训练迁移变得更加简单。 官网链接

AWS K8s 部署架构

Amazon Web Services&#xff08;AWS&#xff09;提供了一种简化的Kubernetes&#xff08;K8s&#xff09;部署架构&#xff0c;使得在云环境中管理和扩展容器化应用变得更加容易。这个架构的核心是AWS EKS&#xff08;Elastic Kubernetes Service&#xff09;&#xff0c;它是…

【Vue】vue项目中命名规范(结合上一篇项目结构)

组件命名规范&#xff1a; 多单词命名&#xff1a; 避免使用单个单词命名组件&#xff0c;因为这可能会导致命名冲突。相反&#xff0c;应该使用描述性的多单词命名&#xff0c;如 UserProfile、SettingsPanel 等。 使用帕斯卡命名法&#xff1a; 组件名称应该以大写字母开头&…

node.js之---事件循环机制

事件循环机制 Node.js 事件循环机制&#xff08;Event Loop&#xff09;是其核心特性之一&#xff0c;它使得 Node.js 能够高效地处理大量并发的 I/O 操作。Node.js 基于 非阻塞 I/O&#xff0c;使用事件驱动的模型来实现异步编程。事件循环是 Node.js 实现异步编程的基础&…

信息科技伦理与道德1:绪论

1 问题描述 1.1 信息科技的进步给人类生活带来的是什么呢&#xff1f; 功能&#xff1f;智能&#xff1f;陪伴&#xff1f;乐趣&#xff1f;幸福&#xff1f; 基于GPT-3的对话Demo DeepFake 深伪技术&#xff1a;通过神经网络技术进行大样本学习&#xff0c;将个人的声音、面…

uniapp 自定义类微信支付键盘 (微信小程序)

效果图 代码: <view class"popups popupsB"><view class"appreciatePrice"><view class"appreciatePriceTitle">赞赏金额</view><view class"appreciatePriceInput flex ac">&#xffe5;<input typ…

电子电气架构 --- 中央处理器HPC及软件架构

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 所谓鸡汤,要么蛊惑你认命,要么怂恿你拼命,但都是回避问题的根源,以现象替代逻辑,以情绪代替思考,把消极接受现实的懦弱,伪装成乐观面对不幸的…

大模型 LangChain 开发框架:Runable 与 LCEL 初探

大模型 LangChain 开发框架&#xff1a;Runable 与 LCEL 初探 一、引言 在大模型开发领域&#xff0c;LangChain 作为一款强大的开发框架&#xff0c;为开发者提供了丰富的工具和功能。其中&#xff0c;Runnable 接口和 LangChain 表达式语言&#xff08;LCEL&#xff09;是构…