Spring全局异常处理

目录

    • 概述
    • 依赖导入
    • 创建全局异常处理
    • 总结

概述

在Spring框架中,全局异常处理主要是通过@ControllerAdvice(或其特化形式@RestControllerAdvice)注解和@ExceptionHandler注解来实现的。这种机制能够捕捉到控制器(@Controller@RestController)中抛出的异常,并允许你定义全局的处理逻辑。

依赖导入

在使用Spring Framework构建应用程序,并希望集成全局异常处理器时,你实际上并不需要添加任何特定的依赖来实现这个功能,因为它是Spring MVC提供的一个内建功能。

但确保你的项目已经包含了Spring MVC相关的依赖。对于使用Spring Boot的项目,你可以通过添加spring-boot-starter-web依赖来集成Spring MVC:

<!-- Maven配置示例 -->
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 其他依赖... -->
</dependencies>

对于非Spring Boot项目,你可以添加相应的Spring MVC依赖,如下所示:

<!-- Maven配置示例 -->
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.3.x</version> <!-- 使用最新的兼容版本 --></dependency><!-- 其他依赖... -->
</dependencies>

这些依赖将自动引入所需的所有组件,从而使你能够使用@ControllerAdvice@RestControllerAdvice@ExceptionHandler注解来处理全局异常。

创建全局异常处理

以下是一个例子,展示了如何使用这些注解来创建一个简单的全局异常处理器:

@ControllerAdvice    // 或者使用 @RestControllerAdvice
public class GlobalExceptionHandler {// 捕获特定类型的异常@ExceptionHandler(CustomException.class)public ResponseEntity<String> handleCustomException(CustomException ex) {// 创建响应实体并自定义相应状态码和信息return new ResponseEntity<>(ex.getMessage(), HttpStatus.BAD_REQUEST);}// 捕获所有类型的异常@ExceptionHandler(Exception.class)public ResponseEntity<String> handleAllExceptions(Exception ex) {// 记录异常(实际生产中你可能会记录更详细的信息)ex.printStackTrace(); // 返回通用错误响应return new ResponseEntity<>("Internal server error occurred.", HttpStatus.INTERNAL_SERVER_ERROR);}// 可以继续添加更多的异常处理方法来处理不同类型的异常
}

全局异常处理器GlobalExceptionHandler可以捕获由应用中的任何控制器抛出的异常。@ExceptionHandler注解标记的方法定义了对特定异常类型的处理逻辑。使用@ExceptionHandler(Exception.class)可以捕获并处理所有类型的异常。在这些处理方法中,可以自定义响应的HTTP状态码和返回消息。

对于REST API,通常使用@RestControllerAdvice来替代@ControllerAdvice,因为它默认地将方法的返回值封装到ResponseEntity中,并序列化为JSON或其他内容类型,而不需要在每个方法上添加@ResponseBody注解,主要用于全局异常处理,数据绑定,和数据预处理。

该注解结合了 @ControllerAdvice@ResponseBody 的特性,表明它是由 @ControllerAdvice 注解的增强版,为 RESTful 服务提供专门的异常处理。与 @ControllerAdvice 结合 @ExceptionHandler 一样,@RestControllerAdvice 也可以结合 @ExceptionHandler 使用,但是它默认为所注解的方法添加了 @ResponseBody 注解的行为。

这意味着,当你在一个以 @RestControllerAdvice 注解的类里面使用 @ExceptionHandler 注解处理异常时,不需要再显式地添加 @ResponseBody 注解。

以下是一个 @RestControllerAdvice 的简单例子,用于捕获并处理特定异常:

@RestControllerAdvice
public class GlobalRestControllerAdvice {@ExceptionHandler(NotFoundException.class)public ResponseEntity<String> handleNotFoundException(NotFoundException ex) {return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());}@ExceptionHandler(Exception.class)public ResponseEntity<String> handleAllException(Exception ex) {return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("An error occurred: " + ex.getMessage());}
}

在上述代码中,GlobalRestControllerAdvice 类添加了 @RestControllerAdvice 注解,这意味着它将作用于应用中的所有 REST 控制器。里面提供了两个异常处理方法,一个用于处理 NotFoundException 类型的异常,返回 HTTP 404 状态和异常信息;而另一个用作默认的异常处理,用来处理所有其他异常并返回 HTTP 500 状态,以及一个通用错误消息。

这种全局异常处理方式简化了异常管理,允许你集中处理所有控制器中抛出的异常,提高代码的可维护性和重用性。

实际行为

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {/*** 捕获业务异常* @param ex* @return*/@ExceptionHandlerpublic Result exceptionHandler(BaseException ex){log.error("异常信息:{}", ex.getMessage());return Result.error(ex.getMessage());}/***  处理SQL异常* @param ex* @return*/@ExceptionHandlerpublic Result exceptionHandler(SQLIntegrityConstraintViolationException ex){String message = ex.getMessage();if (message.contains("Duplicate entry")){String[] split = message.split(" ");String username = split[2];String msg = username+ MessageConstant.ALREADY_EXISTS;return Result.error(msg);}return Result.error(MessageConstant.UNKNOWN_ERROR);}}

这段代码中我们在@ExceptionHandler注解中省略异常类的参数,如果这样做,那表示这个方法将处理该方法参数列表中所声明的异常类型。当注解中没有指定异常类时,它将从方法的参数类型推断。这样的用法要求方法参数必须是异常实例。

在代码例子中:

@ExceptionHandler
public Result exceptionHandler(BaseException ex) { ... }

这个exceptionHandler方法将处理所有类型为BaseException的异常,因为它作为方法的参数被声明了。

在第二个处理程序中:

@ExceptionHandler
public Result exceptionHandler(SQLIntegrityConstraintViolationException ex) { ... }

这个exceptionHandler方法将处理所有类型为SQLIntegrityConstraintViolationException的异常。

这种方式会让你的异常处理器方法看起来更加简洁,而且在只处理单个异常类型的情况下非常实用。但是,如果你打算用一个方法处理多种类型的异常时,你仍然需要在注解中指定这些异常类:

@ExceptionHandler({TypeOneException.class, TypeTwoException.class})
public Result handleMultipleExceptions(Exception ex) {// ...
}

在这里,handleMultipleExceptions方法可以同时处理TypeOneExceptionTypeTwoException类型的异常。

最重要的是要确保异常处理程序可以处理所有的异常情况,并且返回一个合适的响应给用户。省略.class效果上和指定.class是类似的,只要方法参数类型和预期要处理的异常匹配即可。

总结

在实际的应用中,全局异常处理通常会涉及到更复杂的逻辑,如记录详细的错误日志、返回自定义错误对象、集成错误监控服务等。这些处理也都可以通过全局异常处理器来实现和集成。

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

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

相关文章

2024.1.15每日一题

LeetCode 82.删除排序链表中的重复元素 II 82. 删除排序链表中的重复元素 II - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个已排序的链表的头 head &#xff0c; 删除原始链表中所有重复数字的节点&#xff0c;只留下不同的数字 。返回 已排序的链表 。 示例…

常用Java代码-Java中的Optional类和null安全编程

在Java中&#xff0c;Optional 是一个可以为null的容器对象。如果值存在则isPresent()方法返回true。调用get()方法会返回值&#xff0c;如果值为null则抛出NullPointerException。以下是一个详细的代码详解。 在之前的Java版本中&#xff0c;程序员需要手动检查是否为null&am…

docker安装部署Elasticsearch(ES)以及相关配置

Elasticsearch简介 mysql用作持久化存储&#xff0c;ES用作检索 基本概念&#xff1a;index库>type表>document文档 index索引&#xff08;相当于MySQL的数据库&#xff09; 动词&#xff1a;相当于mysql的insert 名词&#xff1a;相当于mysql的db Type类型&#xff…

Jenkins-自动化

定时构建 使用Cron表达式指定执行时间。 # 格式 # ┌──分&#xff08;0 - 59&#xff09; # │ ┌──时&#xff08;0 - 23&#xff09; # │ │ ┌──日&#xff08;1 - 31&#xff09; # │ │ │ ┌─月&#xff08;1 - 12&#xff09; # │ │ │ │ ┌─星期&#…

这本书没有一个公式,却讲透了数学的本质!

《数学的雨伞下&#xff1a;理解世界的乐趣》。一本足以刷新观念的好书&#xff0c;从超市到对数再到相对论&#xff0c;娓娓道来。对于思维空间也给出了一个更容易理解的角度。 作者&#xff1a;米卡埃尔•洛奈 原文完整版PDF&#xff1a;https://pan.quark.cn/s/019bf19c4981…

2024--Django平台开发-Redis持久化、主从复制、哨兵(十)

before Redis基础&#xff1a; Redis的安装&#xff1a;Windows平台、centos7 Windows平台不推荐安装&#xff0c;但是开发阶段&#xff0c;测试使用还是可以的&#xff0c;推荐使用centos等其他Linux平台&#xff0c;因为将来项目部署也要放到Linux云服务器上。 Redis的通用…

电子学会C/C++编程等级考试2023年09月(六级)真题解析

C/C++编程(1~8级)全部真题・点这里 第1题:生日相同 在一个有180人的大班级中,存在两个人生日相同的概率非常大,现给出每个学生的名字,出生月日。试找出所有生日相同的学生。 时间限制:1000 内存限制:65536 输入 第一行为整数n,表示有n个学生,n ≤ 180。此后每行包含一…

PL/1语言 :上古伟大的操作系统IBM System/3603的开发编程语言

PL/I (Programming Language One&#xff0c;发音为/pi /I w / n/&#xff0c;有时也写为PL/1)[1]是最初由IBM开发的一种过程式、命令式的计算机编程语言。它是为科学、工程、商业和系统编程而设计的。自20世纪60年代引入以来&#xff0c;它一直被学术、商业和工业组织不断使用…

14. 接口(适配器设计模式)

接口 接口1. 定义格式2. 成员特点2.1 成员方法2.2 默认方法2.3 静态方法2.4 变量 3. 接口的实现3.1 实现规则3.2 实现格式3.2.1 单实现格式3.2.2 多实现格式 3.3 接口的继承3.3.1 接口与类的继承3.3.2 接口与接口的继承 4.类与接口的区别5. 注意事项 适配器设计模式 接口 接口…

深入理解 go reflect - 要不要传指针

在我们看一些使用反射的代码的时候&#xff0c;会发现&#xff0c;reflect.ValueOf 或 reflect.TypeOf 的参数有些地方使用的是指针参数&#xff0c;有些地方又不是指针参数&#xff0c; 但是好像这两者在使用上没什么区别&#xff0c;比如下面这样&#xff1a; var a 1 v1 :…

dubbo如何实现像本地方法一样调用远程方法

Dubbo 实现像本地方法一样调用远程方法的核心技术是动态代理。Dubbo 使用JDK 动态代理或者字节码增强技术&#xff0c;生成一个代理类&#xff0c;该代理类实现了本地接口&#xff0c;具有本地接口的所有方法。在调用本地接口方法时&#xff0c;会通过代理类的 invoke 方法将请…

golang Iris 运行多个应用

在 Iris 里面&#xff0c;提供了一种方式可以让我们同时运行多个应用&#xff1a; 这里说的应用只是一个 Iris 框架实例&#xff0c;这个实例可以有完全不同的路由定义、中间件等。 不同端口不同应用 package mainimport ("log""net/http""time"…

二叉树的四种遍历方式

二叉树的遍历 二叉树常见的遍历方式有层序遍历&#xff0c;前序遍历&#xff0c;中序遍历&#xff0c;后序遍历 层序遍历 从顶部到底部&#xff0c;逐层进行遍历&#xff0c;且每一层按照从左到右的顺序遍历 层序遍历本质上是广度优先遍历(BFS) 代码实现 广度优先遍历一般使用队…

AI教我学编程之C#类的基本概念(1)

前言 在AI教我学编程之C#类型 中&#xff0c;我们学习了C#类型的的基础知识&#xff0c;而类正是类型的一种. 目录 区分类和类型 什么是类&#xff1f; 什么是类型&#xff1f; 追问 实操 总结 区分类和类型 在 C# 中&#xff0c;类是类型的一种。C# 是一种面向对象的编程…

js 数组内置的方法

JavaScript中数组内置了许多有用的方法&#xff0c;可以方便地操作和处理数组。以下是一些常用的数组方法&#xff1a; push()&#xff1a;向数组末尾添加一个或多个元素&#xff0c;并返回新数组的长度。pop()&#xff1a;移除数组末尾的元素&#xff0c;并返回被移除的元素。…

uniapp如何调用ANDROID原生函数

在 UniApp 中调用 Android 原生函数&#xff0c;通常需要使用 UniApp 的插件系统。以下是调用 Android 原生函数的一般步骤&#xff1a; 安装插件&#xff1a;首先&#xff0c;确保你已经安装了对应的插件。你可以在 UniApp 插件市场 中搜索并安装你需要的插件。对于 Android 原…

利用XSS漏洞打cookie

目录 1、为什么要打cookie&#xff1f; 2、怎样利用XSS来打cookie&#xff1f; 3、利用Bluelotus_xssReceiver平台来打cookie 4、利用beef-xss平台来打cookie 上一篇给大家介绍了xss漏洞的基础知识&#xff0c;在本篇章将会介绍和演示一下利用xss漏洞打cookie的演示&#x…

复习回顾、静态、继承、引用类型使用

今日内容 复习回顾 定义类。一个Java文件可以定义多个类。但是只有一个类是用public修饰&#xff0c;public修饰的类名必须称为Java文件名。类中有且仅有5大成分&#xff08;五大金刚&#xff09; 成员变量Field&#xff1a;描述类或者对象的属性信息的。成员方法Method&#…

DAY8--learning english

一、积累 1.haunt Why Ghost dont haunt chinese. 为什么鬼不会出现在中国人旁边? 2.confess i have a confession to make ... I actally a blind. 我要坦白一件事……我其实是个盲人。 3.brake Press S button to brake, or to reverse if the vehicle has stopped, 按住…

Spring MVC中的常用注解及其用法

文章目录 一、建立连接二、接收请求2.1请求中带有一个参数2.2请求中带有多个参数2.3用对象接收请求中的参数2.4对请求中的参数进行重命名2.5请求参数中带有数组2.6请求参数中带有集合2.7json字符串和Java对象互转2.8前端传递json数据给后端、json数据在请求正文中、后端接收jso…