springboot实现全局异常捕获

导言:

为什么要做异常处理:
原因有三:
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.hqwc.cn/news/26523.html

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

相关文章

分布式应用之Zookeeper和Kafka

分布式应用之Zookeeper和Kafka 一、Zookeeper 1.定义 分布式系统管理框架&#xff0c;主要用来解决分布式集群中应用系统的一致性问题 相当于各种分布式应用服务的 注册中心 文件系统 通知机制2.特点 &#xff08;1&#xff09;Zookeeper&#xff1a;一个领导者&#…

【Java基础教程】(十五)面向对象篇 · 第九讲:抽象类和接口——定义、限制与应用的细节,初窥模板设计模式、工厂设计模式与代理设计模式~

Java基础教程之面向对象 第九讲 本节学习目标1️⃣ 抽象类1.1 抽象类定义1.2 抽象类的相关限制1.3 抽象类应用——模板设计模式 2️⃣ 接口2.1 接口定义2.2 接口的应用——标准2.3 接口的应用——工厂设计模式 (Factory)2.4 接口的应用——代理设计模式 (Proxy) 3️⃣ 抽象类与…

数据库的扩展策略

了解不同的数据库扩展技术可以帮助我们选择适合我们需求和目的的合适策略。 因此&#xff0c;在本文中&#xff0c;我们将展示不同的解决方案和技术&#xff0c;用于扩展数据库服务器。它们分为读取和写入策略。 读取/加载 有时我们的应用程序承受着巨大的负载。为了解决这个…

【VSCode | 使用技巧集锦】中文插件突然失效、配置单个工程(工作区)编码

目录 ✨技巧一&#xff1a;中文插件失效的解决办法✨技巧二&#xff1a;配置单个工程(工作区)编码 ✨技巧一&#xff1a;中文插件失效的解决办法 问题描述&#xff1a;VSCode之前安装了中文插件&#xff0c;可以正常汉化&#xff0c;用了一段时间都没问题&#xff0c;今天打开v…

51单片机的智能交通控制系统【含仿真+程序+演示视频带原理讲解】

51单片机的智能交通控制系统【含仿真程序演示视频带原理讲解】 1、系统概述2、核心功能3、仿真运行及功能演示4、程序代码 1、系统概述 该系统由AT89C51单片机、LED灯组、数码管组成。通过Protues对十字路口红绿灯控制逻辑进行了仿真。 每个路口包含了左转、右转、直行三条车道…

【UE4 塔防游戏系列】08-敌人到达终点对玩家造成伤害

目录 效果 步骤 一、敌人到终点时扣除玩家生命值 二、显示玩家生命值 效果 可以看到敌人进入终点后&#xff0c;左上角的玩家生命值会减少。 步骤 一、敌人到终点时扣除玩家生命值 新建一个Actor蓝图类&#xff0c;命名为“BP_EnemyEndPlace”&#xff0c;用来表示终点…

Pytest测试框架搭建需求及实现方案

目录 框架需求及实现方案 框架需求 实现方案 支持接口自动化、Web UI自动化及App自动化# 可以批量运行用例并生成测试报告 测试完成发送邮件 提供灵活的运行方式&#xff0c;如按功能模块运行、按脚本运行、按用例等级运行等等 提供运行日志方便定位问题 支持切换环境 …

三季度上市,比亚迪海豹DM-i内饰官图发布,延续海洋风格

据报道&#xff0c;比亚迪海洋网旗下全新车型海豹 DM-i今日发布了内饰官方图片。新车内部采用了独特的“海洋美学”设计理念&#xff0c;并体现了海洋网最新一代内饰风格。消息称&#xff0c;这款车型将于第三季度上市&#xff0c;定位为中大型混合动力轿车。 值得注意的是&…

MSA【1】:Segment Anything Model for Medical Image Analysis: an Experimental Study

文章目录 前言1. Abstraction & Introduction1.1. Abstraction1.2. Introduction1.2.1. What is SAM?1.2.2. How to segment medical images with SAM? 2. Methodology2.1. SAM is used in the process of segmentation of medical images2.1.1. Semi-automated annotati…

3.Cesium中实体Entity创建(超详细)

前言 在学习 Cesium 的过程中&#xff0c;我发现官方文档冗长且阅读困难&#xff0c;为此我结合官方文档与自己的学习笔记&#xff0c;对其进行归类总结&#xff1b;本文中&#xff0c;我将介绍 Cesium 中创建实体的方法&#xff0c;并对其进行分类&#xff0c;帮助读者快速理解…

集成VCO-Cadence ADE相位噪声分析

集成VCO-Cadence ADE相位噪声分析 简介环境软件工艺 参考振荡器原理图相位噪声说明pss设置1234 pnoise设置12345 结果 简介 本文主要是使用Cadence ADE仿真1GHz交叉耦合振荡器&#xff0c;得到相位噪声曲线&#xff0c;主要记录仿真设置过程&#xff0c;仅供参考&#xff0c;如…

数据结构01-线性结构-链表栈队列-队列篇

文章目录 参考&#xff1a;总结大纲要求线性结构-队列QQ号码解密 参考&#xff1a; 总结 本系列为C数据结构系列&#xff0c;会介绍 线性结构&#xff0c;简单树&#xff0c;特殊树&#xff0c;简单图等。本文为线性结构部分。 大纲要求 线性结构 【 3 】链表&#xff1a;单…