springboot实现全局异常捕获

news2025/2/3 9:06:05

导言:

为什么要做异常处理:
原因有三:
1、将系统产生的全部异常统一捕获处理。

2、自定义异常需要由全局异常来捕获。

3、JSR303规范的validator参数校验器、参数校验不通过、本身无法使用try…catch

其实对于前后端分离的项目做异常处理是很有必要的
在不出异常的情况下,后端将数据封装成固定格式(也就是R类)返回给前端,方便前端去解析数据
例如如下R类:

@Data
public class R<T> implements Serializable {

    private Integer code; //编码:1成功,0和其它数字为失败

    private String msg; //错误信息

    private T data; //数据

    private Map map = new HashMap(); //动态数据

    public static <T> R<T> success(T object) {
        R<T> r = new R<T>();
        r.data = object;
        r.code = 1;
        return r;
    }
    public static <T> R<T> success(String msg,T object) {
        R<T> r = new R<T>();
        r.data = object;
        r.code = 1;
        r.msg = msg;
        return r;
    }

    public static <T> R<T> error(String msg) {
        R r = new R();
        r.msg = msg;
        r.code = 0;
        return r;
    }

    public static <T> R<T> success(String msg) {
        R r = new R();
        r.msg = msg;
        r.code = 1;
        return r;
    }

    public R<T> add(String key, Object value) {
        this.map.put(key, value);
        return this;
    }

}

正常不出异常的情况下根据controller层返回的数据:
controller层

    //正常情况
    @GetMapping("/hhy/1")
    public R info(){
        int i = 60/1;
        return R.success("成功",i);
    }

请求成功返回给前端数据:
在这里插入图片描述
在这里插入图片描述
在出异常的情况下(模拟除0异常):
controller层

    //空指针异常
    @GetMapping("/hhy/2")
    public R info2(){
        int i = 60/0;
        return R.success("成功",i);
    }

出现异常前端拿不到数据,并且后端报错:
在这里插入图片描述
前端:
在这里插入图片描述
后端:
在这里插入图片描述

这样虽然后端可以知道异常情况,但是前端就难受了,啥也不知道,就知道出错了;

重点来了!!!!!

这里就可以体现全局异常处理器的重要性了;让前端的兄弟好受一点。

实现全局异常处理器捕获异常

举例:异常还是除0 异常:

java.lang.ArithmeticException: / by zero

这里的异常就是ArithmeticException,异常信息为/ by zero

编写全局异常捕获类:GlobalExceptionHandler

/**
 * 全局异常捕获
 */
@Slf4j
@ControllerAdvice(annotations = {RestController.class, Controller.class})
//只要类的注解上有这些注解。那么发生的异常都能被捕获到
@ResponseBody
public class GlobalExceptionHandler {
    /**
     * 处理除0异常捕获
     * @param exception
     * @return
     */
    @ExceptionHandler(ArithmeticException.class)//ArithmeticException异常类型通过注解拿到
    public R<String> exceptionHandler(ArithmeticException exception){
            log.error(exception.getMessage());//在控制台打印错误信息
                return R.error(exception.getMessage());

    }
}

此时在controller层出现ArithmeticException(除0)异常时就会被全局异常处理器捕获到:
后端::相比之前一大串报错,是不是很清爽
在这里插入图片描述
前端:

在异常处理器里面已将错误信息封装成返回类R返回给前端

在这里插入图片描述

相比之前返回给前端的一大串杂七杂八的,这个是不是超级清爽,并且可以根据code码在前端将错误信息设置警告框

在这里插入图片描述

这样前端的兄弟看到信息就知道,嗷嗷 后端出问题了 问题是除0异常,这样就可以安心的去甩锅给后端的哥们了;

实现原理:

想必注意到这个注解:

@ControllerAdvice(annotations = {RestController.class, Controller.class})

意思只要类的注解上有这些注解。那么发生的异常都能被捕获到,例如例子中出现的异常的类的注解为:
在这里插入图片描述

异常捕获类的@ResponseBody注解

当我们在全局异常处理中使用@ResponseBody注解时,它可以将异常信息序列化为JSON或其他格式的字符串,并作为HTTP响应的Body部分返回给客户端。

这就是为什么前端的兄弟能看到如此清爽的返回数据格式:
在这里插入图片描述
不加@ResponseBody那就智能看到又臭又长的这个:
在这里插入图片描述

@ExceptionHandler(ArithmeticException.class)

具体拦截类上的@ExceptionHandler注解主要是指定去捕获哪一种异常,这个很好理解

需要拦截捕获哪一类异常就去指定具体的类异常,捕获原理如上;

but··························

那么如果用户在操作的时候,出现一些有违背业务逻辑的情况下,我们也视为操作异常,抛出自定义的异常,返回给前端,然后告诉用户不能这么操作

自定义异常处理

1、首先要编写异常自定义处理类:

CustomException

public class CustomException extends RuntimeException{
    /**
     *  自定义业务异常类
     * @param message
     */
    public CustomException(String message){
        super(message);
        log.info(message.toString());
    }
}

这里将业务层抛出的异常信息捕获到,然后归类为runtime运行时异常,
然后交给全局异常处理器去处理,给前端提供错误信息

2、在全局异常类里面去捕获自定义异常CustomException

 /**
     * 将业务层抛出的异常信息捕获到,然后交给全局异常处理器去处理,给前端提供错误信息
     * @param exception
     * @return
     */
    @ExceptionHandler(CustomException.class)//RuntimeException异常类型通过注解拿到
    public R<String> exceptionCategoryDelete(CustomException exception){
        log.error(exception.getMessage());//在控制台打印错误信息
            return R.error(exception.getMessage());

    }

原理上面已经讲过了,不在赘述

那我们来测试一下,在业务层抛出一个CustomException ,看能不能被全局异常类捕获到:
后端:
在这里插入图片描述
在这里插入图片描述

前端:
在这里插入图片描述
在这里插入图片描述

这样我们就可以愉快的解决异常问题了

这里稍稍解释下@ControllerAdvice注解

@ControllerAdvice注解是基于Spring框架的AOP(面向切面编程)实现的。AOP是一种编程范式,它通过在应用程序运行时,将横跨多个组件的行为进行分离和管理。

在Spring框架中,通过AOP可以将一些通用的横切关注点(比如异常处理、日志记录等)从业务逻辑中剥离出来,并以声明的方式进行集中管理。@ControllerAdvice注解就是利用了AOP的机制,在应用程序的控制器层进行统一的全局异常处理和数据绑定。

底层实现上,@ControllerAdvice注解使用了Spring的核心功能之一:切面(Aspect)和增强(Advice)。通过定义一个带有@ControllerAdvice注解的类,并在其中定义不同类型的增强(比如@ExceptionHandler注解用于异常处理),Spring会在运行时动态生成代理对象,将增强逻辑织入到目标控制器的方法调用中。

总结来说,@ControllerAdvice注解的底层实现基于Spring框架的AOP机制,通过切面和增强的方式,实现了全局异常处理和数据绑定的功能。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ROS:导航功能详解

目录 一、导航简介1.1导航概念1.2导航作用1.3导航模块简介1.3.1全局地图1.3.2自身定位1.3.3路径规划1.3.4运动控制1.3.5环境感知 1.4导航条件1.4.1硬件1.4.2软件 二、坐标系2.1坐标系简介2.2坐标系特点2.3坐标系变换 三、导航功能实现3.1SLAM建图3.1.1gmapping简介3.1.2gmappin…

【VUE】解决VU2项目图片视频加载缓慢/首屏加载白屏的问题

1 问题描述 前端项目中&#xff0c;有时候会出现图片视频加载缓慢、首屏加载白屏的问题 之前写了一篇在VU3项目中的解决方案&#xff0c; 现在讲一下在 Vue2 项目中的解决方法&#xff0c;方法思路都差不多&#xff0c;在代码示例上会有一些小差别 2 原因分析 通常是由以下原因…

辅助驾驶功能开发-功能规范篇(22)-6-L2级辅助驾驶方案功能规范

1.3.6 ELK 系统功能定义 ELK全称Emergency Lane Keeping&#xff0c;即紧急车道保持。当车辆与道路边界护栏&#xff08;包含隔离带护栏、路锥、水马&#xff09; 有碰撞危险或当车辆正偏出道路边沿且存在“对向来车”或“后向来车”与本车有碰撞风险时&#xff0c;通过给与转向…

Redis源码篇- SDS

Redis对于String类型&#xff0c;底层使用的是SDS&#xff08;简单动态字符串&#xff09;&#xff0c;而不是常规的C语言的字符数组 。 通常在C中&#xff0c;定义一个字符串&#xff0c;方式是通过字符数组表示&#xff0c;同时结尾使用/0表示结束&#xff1a;char [] &quo…

C语言 与 C++ 通讯录对比实现(附带源码)

目录 1.通讯录的基本框架 C语言版 C版 2.增加联系人 C语言版 C版 3.删除联系人 C语言版 C版 4.查找与打印联系人 C语言版 C版 5.修改联系人 C语言版 C版 6.排序联系人 C语言版 C版 7.其他 8.总结 本文章将对C语言、C版本的通讯录进行对比实现。其中C版本引入大量C语言没有的特性…

第 5 章 Spark Shuffle 解析

第 5 章 Spark Shuffle 解析 5.1 Shuffle 的核心要点1. 数据分区&#xff1a;2.数据传输&#xff1a;3. 数据排序&#xff1a;4.数据聚合&#xff1a;5. 数据重分发&#xff1a;6.数据持久化&#xff1a;5.1.1 ShuffleMapStage 与 ResultStage 5.2 HashShuffle 解析5.2.1 未优化…

KUKA机器人_外部安全条件不满足时,如何操作机器人的方法

KUKA机器人_外部安全条件不满足时&#xff0c;如何操作机器人的方法 如果大家在做项目时&#xff0c;控制系统尚未完成&#xff0c;外部紧急停止等安全条件尚未满足时&#xff0c;但是此时想操作或移动机器人&#xff0c;有办法吗&#xff1f; 答案是有。 具体的方法可参考以…

驾驶证——科目一笔记(二)

知识点1&#xff1a;通行规定 有加速&#xff08;x&#xff09; 各种礼让&#xff08;√&#xff09; 减速慢行、减速靠右、减速或停车、停车避让&#xff08;√&#xff09; 不用减速慢行、无需减速、不必减速&#xff08;x&#xff09; 不得&#xff08;√&#xff09; …

【文档模板】产品故障分析报告

今天和大家分享产品故障分析报告的文档模板。产品故障分析报告是一份文件&#xff0c;通常由技术团队、工程师或相关专业人员编写&#xff0c;用于详细描述和分析出现在系统、设备、产品或服务中的故障原因和根本原因。这些报告旨在对故障进行系统性的研究&#xff0c;以便团队…

Windows沙盒的安装与配置

沙盒安装 1、打开控制面板 2、选择程序与功能 3、勾选Windows 沙盒&#xff0c;然后点击确定&#xff0c;等待安装完成即可。 沙盒配置 Windows 沙盒支持简单的配置文件&#xff0c;这些文件为沙盒提供最少的自定义参数集。 此功能可与 Windows 10 内部版本 18342 或 Windows…

数据库管理-第九十二期 一周故障汇总(20230717)

第九十二期 一周故障汇总&#xff08;20230717&#xff09; 距离上一篇已经过了整整一周了&#xff0c;平时我虽然不是生产队的驴&#xff0c;但是一周一篇以上的数量还是维持了一段时间了。为啥上周只写了一篇&#xff0c;因为各种故障、各种保障、各种割接忙了整整一周&…

数据分析师:解读数据背后的故事

数据在当今信息时代中扮演着至关重要的角色&#xff0c;而数据分析师则是解读和发掘数据中隐藏信息的关键人物。作为数据分析师&#xff0c;他们运用统计学、机器学习和数据可视化等技术手段&#xff0c;从海量的数据中提取出有价值的信息和洞察&#xff0c;并将其转化为可供决…

大数据学习02-Hadoop分布式集群部署

操作系统&#xff1a;centos7 软件环境&#xff1a;jdk8、hadoop-2.8.5 一、创建虚拟机 1.下载VMware,建议支持正版 2.安装到Widows目录下任意位置即可&#xff0c;安装目录自定义。打开VMware&#xff0c;界面如下&#xff1a; 3.创建虚拟机 创建虚拟机—>选择自定义 …

kafka消息队列最常用的两种模式,以及应用场景

目录 一、发布-订阅模式 二、点对点模式 三、应用场景 一、发布-订阅模式 发布-订阅模式是最常见的消息传递模式&#xff0c;其中消息发布者将消息发送到一个或多个主题&#xff08;Topic&#xff09;&#xff0c;而订阅者可以选择订阅一个或多个主题来接收消息。每个订阅者…

在嵌入式系统开发培训中常用的数据库有哪些种?

数据库是一种储存和管理、组织数据的仓库&#xff0c;在嵌入式开发当中起到至关重要的作用。一个在嵌入式培训中&#xff0c;我们可学习使用的数据库有多种&#xff0c;每种数据库都会呈现出不同的一面&#xff0c;那么我们在嵌入式系统开发培训中可用到的数据库都有哪几种&…

JQuery(二):DOM操作、动画、遍历、事件绑定

1.DOM操作 1.1内容操作 html(): 获取/设置元素的标签体内容 <a><font>内容</font></a> --> <font>内容</font>text(): 获取/设置元素的标签体纯文本内容 <a><font>内容</font></a> --> 内容val()&am…

RK3588+FPGA视频实时处理与双屏显示、存储解决方案

主板平台的主要功能电路示意图 在ARM端: 脚踏开关是电平输入10 口&#xff0c;双路。 触摸面板与主板的连接方式为 UART 外加12V 电源。 键盘为自开发产品&#xff0c;通过USB透传 UART&#xff0c;并传递12V电源USB、千兆网络为主板上的接口&#xff0c;USB 为3.0版本host 接口…

Hadoop 之 单机部署和测试(一)

Hadoop单机部署和测试 一.单机部署1.安装 JDK&#xff08;JDK11&#xff09;2.安装 HADOOP3.测试 一.单机部署 系统版本&#xff1a;cat /etc/anolis-release1.安装 JDK&#xff08;JDK11&#xff09; #!/bin/bashTOP_PATH$(pwd) JAVA_PATH/usr/local/java FILEls $TOP_PATH/…

【Linux | Shell】结构化命令2 - test命令、方括号测试条件、case命令

目录 一、概述二、test 命令2.1 test 命令2.2 方括号测试条件2.3 test 命令和测试条件可以判断的 3 类条件2.3.1 数值比较2.3.2 字符串比较 三、复合条件测试四、if-then 的高级特性五、case 命令 一、概述 上篇文章介绍了 if 语句相关知识。但 if 语句只能执行命令&#xff0c…

兴达易控modbus转profinet网关与三菱变频器通讯

本案例分享兴达易控modbus转profinet网关&#xff08;MDPN100&#xff09;连接西门子1200plc&#xff0c;实现三菱变频器485通讯兼容转modbusTCP通信&#xff0c;在博图中配置。 拓展图 打开博图&#xff0c;并添加PLC 加载由兴达易控免费提供的modbus转profinet GSD文件 安装网…