【实用知识】Spring Boot 优雅捕捉异常的几种姿势

👉博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主

⛪️ 个人社区:个人社区
💞 个人主页:个人主页
🙉 专栏地址: ✅ Java 中级
🙉八股文专题:剑指大厂,手撕 Java 八股文

在这里插入图片描述

文章目录

    • Spring Boot 如何优雅捕捉异常?
      • 1. 全局异常处理器
      • 2. 控制器特定的异常处理器
      • 3. 使用 `@ControllerAdvice` 进行集中式异常处理
      • 4. 自定义异常
      • 5. 统一错误响应格式
      • 6. 日志记录
      • 写在最后

Spring Boot 如何优雅捕捉异常?

在Spring Boot中,优雅地捕捉和处理异常可以提高应用程序的健壮性和用户体验。Spring Boot提供了多种方式来处理异常,包括全局异常处理器、控制器特定的异常处理器以及使用@ControllerAdvice注解的集中式异常处理。

1. 全局异常处理器

你可以创建一个全局异常处理器来捕获整个应用中的异常。这通常通过实现HandlerExceptionResolver接口或继承ResponseEntityExceptionHandler类来完成。

使用 ResponseEntityExceptionHandler

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {@ExceptionHandler(value = { IllegalArgumentException.class })@ResponseStatus(HttpStatus.BAD_REQUEST)public ResponseEntity<ErrorResponse> handleIllegalArgumentException(IllegalArgumentException ex) {ErrorResponse error = new ErrorResponse("Invalid input", ex.getMessage());return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);}@ExceptionHandler(value = { RuntimeException.class })@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public ResponseEntity<ErrorResponse> handleRuntimeException(RuntimeException ex) {ErrorResponse error = new ErrorResponse("Internal server error", ex.getMessage());return new ResponseEntity<>(error, HttpStatus.INTERNAL_SERVER_ERROR);}
}// 自定义错误响应类
class ErrorResponse {private String message;private String details;public ErrorResponse(String message, String details) {this.message = message;this.details = details;}// Getters and setters
}

2. 控制器特定的异常处理器

你也可以在单个控制器内定义异常处理器方法,只处理该控制器内的异常。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;@RestController
@RequestMapping("/api/users")
public class UserController {@RequestMapping("/get")public User getUser() {// 业务逻辑if (someCondition) {throw new IllegalArgumentException("Invalid user ID");}return new User();}@ExceptionHandler(value = { IllegalArgumentException.class })public ResponseEntity<ErrorResponse> handleIllegalArgumentException(IllegalArgumentException ex) {ErrorResponse error = new ErrorResponse("Invalid input", ex.getMessage());return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);}
}

3. 使用 @ControllerAdvice 进行集中式异常处理

@ControllerAdvice 是 Spring 提供的一个注解,用于定义全局异常处理类。这个类可以包含多个 @ExceptionHandler 方法,每个方法处理不同类型的异常。

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(value = { IllegalArgumentException.class })@ResponseStatus(HttpStatus.BAD_REQUEST)public ErrorResponse handleIllegalArgumentException(IllegalArgumentException ex) {return new ErrorResponse("Invalid input", ex.getMessage());}@ExceptionHandler(value = { RuntimeException.class })@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public ErrorResponse handleRuntimeException(RuntimeException ex) {return new ErrorResponse("Internal server error", ex.getMessage());}
}// 自定义错误响应类
class ErrorResponse {private String message;private String details;public ErrorResponse(String message, String details) {this.message = message;this.details = details;}// Getters and setters
}

4. 自定义异常

为了更好地控制异常处理,你可以创建自定义异常类,并在需要的地方抛出这些异常。

public class ResourceNotFoundException extends RuntimeException {public ResourceNotFoundException(String message) {super(message);}
}

然后在全局异常处理器中处理这些自定义异常:

@ControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(value = { ResourceNotFoundException.class })@ResponseStatus(HttpStatus.NOT_FOUND)public ErrorResponse handleResourceNotFoundException(ResourceNotFoundException ex) {return new ErrorResponse("Resource not found", ex.getMessage());}// 其他异常处理器
}

5. 统一错误响应格式

为了保持一致性,建议定义一个统一的错误响应格式。这样客户端可以更容易地解析和处理错误信息。

public class ErrorResponse {private int status;private String message;private String details;public ErrorResponse(int status, String message, String details) {this.status = status;this.message = message;this.details = details;}// Getters and setters
}

6. 日志记录

在异常处理器中添加日志记录,以便于调试和监控。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;@ControllerAdvice
public class GlobalExceptionHandler {private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);@ExceptionHandler(value = { RuntimeException.class })@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)public ErrorResponse handleRuntimeException(RuntimeException ex) {logger.error("Unexpected error occurred: ", ex);return new ErrorResponse(HttpStatus.INTERNAL_SERVER_ERROR.value(), "Internal server error", ex.getMessage());}// 其他异常处理器
}

写在最后

通过上述方法,你可以在Spring Boot应用中优雅地捕捉和处理异常。使用@ControllerAdvice可以集中管理异常处理逻辑,而自定义异常和统一的错误响应格式则有助于提高代码的可维护性和一致性。同时,日志记录对于调试和监控也非常重要。

精彩专栏推荐订阅:在下方专栏👇🏻
✅ 2023年华为OD机试真题(A卷&B卷)+ 面试指导
✅ 精选100套 Java 项目案例
✅ 面试需要避开的坑(活动)
✅ 你找不到的核心代码
✅ 带你手撕 Spring
✅ Java 初阶

在这里插入图片描述

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

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

相关文章

JVM(HotSpot):GC之G1垃圾回收器

文章目录 一、简介二、工作原理三、Young Collection 跨代引用四、大对象问题 一、简介 1、适用场景 同时注重吞吐量&#xff08;Throughput&#xff09;和低延迟&#xff08;Low latency&#xff09;&#xff0c;默认的暂停目标是 200 ms超大堆内存&#xff0c;会将堆划分为…

华为云弹性云服务器无法登录远程操作

遇到的问题&#xff1a; 就是你在创建弹性云服务器的时候选择了没有子网的虚拟私有云&#xff0c; 你属于误删了虚拟私有云的子网&#xff0c;自己没有注意看 如果在华为云创建弹性云服务器时选择的虚拟私有云&#xff08;VPC&#xff09;没有配置子网&#xff0c;那么在尝试远…

【mysql 进阶】2-1. MySQL 服务器介绍

MySQL 服务器简介 通常所说的 MySQL 服务器指的是mysqld程序&#xff0c;当运⾏mysqld后对外提供MySQL 服务&#xff0c;这个专题的内容涵盖了以下关于MySQL 服务器以及相关配置的内容&#xff0c;包括&#xff1a; 服务器⽀持的启动选项。可以在命令⾏和配置⽂件中指定这些选…

嵌入式C语言字符串具体实现

大家好,今天主要给大家分享一下,如何使用C语言进行字符串操作与实现。 第一:字符串相关操作实现 复制函数五个基本要素: 头文件:#include <string.h> 函数原型:strcpy(char dest[],char src[]) -----string copy 功能:把src数组中\0之前的所有字符,连同‘\…

在xml 中 不等式 做转义处理的问题

对于这种要做转义处理&#xff0c;<![CDATA[ < ]]>

讲一讲 kafka 的 ack 的三种机制?

大家好&#xff0c;我是锋哥。今天分享关于【K讲一讲 kafka 的 ack 的三种机制&#xff1f;】面试题&#xff1f;希望对大家有帮助&#xff1b; 讲一讲 kafka 的 ack 的三种机制&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Kafka的消息确认机制&…

【计网】UDP Echo Server与Client实战:从零开始构建简单通信回显程序

目录 前言&#xff1a; 1.实现udpserver类 1.1.创建udp socket 套接字 --- 必须要做的 socket&#xff08;&#xff09;讲解 代码实现&#xff1a;​编辑 代码讲解&#xff1a; 1.2.填充sockaddr_in结构 代码实现&#xff1a; 代码解析&#xff1a; 1.3.bind sockfd和…

Vue2自定义指令及插槽

这里写目录标题 自定义指令基础语法指令的值封装v-loading指令 插槽默认插槽后备内容&#xff08;插槽的默认值&#xff09;具名插槽作用域插槽 自定义指令 自定义指令&#xff1a;自己定义的指令&#xff0c;封装一些dom操作&#xff0c;扩展额外功能 基础语法 全局注册&am…

2024年TI杯E题-三子棋游戏装置方案分享-jdk123团队-第四弹 第二题

往期回顾 前期准备 摄像头bug解决 手搓机械臂 视觉模块的封装 下面是题目部分&#xff1a; 第二问我们继续延续第一问的思路&#xff1a; 将棋子坐标与棋盘上标定的坐标进行绑定。 代码展示&#xff1a; import RPi.GPIO as GPIO import time import cv2 import numpy as…

【Qt】常用控件:按钮类控件

思维导图&#xff1a; 一、Push Button 我们可以使用 QPushButton 表示一个按钮&#xff0c;这也是当前我们最熟悉的一个控件。QPushButton继承于QAbstractButton。这个类是一个抽象类&#xff0c;是按钮的父类。 1.1 常用的属性 属性说明text按钮中的文本icon按钮中的图标ic…

Flutter登录界面使用主题

Now, let’s use the theme we initially created in our main function for a simple login screen: 现在&#xff0c;让我们使用最初在主函数中创建的主题来制作一个简单的登录屏幕&#xff1a; Create a Login Screen Widget: Inside the main.dartfile, create a new wid…

基于Springboot+Vue的候鸟监测数据管理系统 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 这个系…

MySQL 字段类型介绍

在 MySQL 中&#xff0c;设计数据库表时&#xff0c;需要根据数据的实际需求选择合适的数据类型&#xff0c;以确保数据存储的准确性和节省存储空间。MySQL 提供了丰富的字段类型&#xff0c;主要分为以下几类&#xff1a;数值类型、字符串类型、日期时间类型、和JSON类型等。 …

ffmpeg视频滤镜:定向模糊-dblur

滤镜简述 dblur 官网链接 > https://ffmpeg.org/ffmpeg-filters.html#dblur 有一个模糊滤镜&#xff0c;我试了一下&#xff0c;没有感觉到它的特殊之处, 这里简单介绍一下。 滤镜使用 滤镜的参数 angle <float> ..FV.....T. set angle (from 0 t…

019集——global全局引用报错解决方案(全局using指令在c#7.3中不可用)(CAD—C#二次开发入门)

如图&#xff0c;所示&#xff0c;全局引用global using出现报错&#xff1a; 解决方案如下&#xff1a; 新建一个类库&#xff0c;standard2.0版本。不要选.netframework 首先vs右下角更新vs版本 打开项目所在文件夹 找到项目文件.csproj&#xff0c;记事本打开。属性组位置加…

Go语言开发环境搭建

文档说明 本文作者:SwBack 创作时间:2022‎年‎6‎月‎8‎日 ‏‎18:46:21 知乎:https://www.zhihu.com/people/back-88-87 CSDN:https://blog.csdn.net/qq_30817059 百度搜索: SwBack系统: Windows 11 go 1.18.2 安装包下载 安装包下载链接 直接默认NEXT 查看Go版本 查看Go…

Coppelia Sim (v-REP)仿真 机器人3D相机手眼标定与实时视觉追踪 (二)

coppelia sim[V-REP]仿真实现 机器人于3D相机手眼标定与实时视觉追踪 二 zmq API接口python调用python获取3D相机的数据获取彩色相机的数据获取深度相机的数据用matpolit显示 python控制机器人运动直接控制轴的位置用IK运动学直接移动到末端姿态 相机内参的标定记录拍照点的位置…

Java面向对象编程高阶(一)

Java面向对象编程高阶&#xff08;一&#xff09; 一、关键字static1、static修饰属性2、静态变量与实例变量的对比3、static修饰方法4、什么时候将属性声明为静态的&#xff1f;5、什么时候将属性声明为静态的&#xff1f;6、代码演示 一、关键字static static用来修饰的结构…

Javaee---多线程(一)

文章目录 1.线程的概念2.休眠里面的异常处理3.实现runnable接口4.匿名内部类子类创建线程5.匿名内部类接口创建线程6.基于lambda表达式进行线程创建7.关于Thread的其他的使用方法7.1线程的名字7.2设置为前台线程7.3判断线程是否存活 8.创建线程方法总结9.start方法10.终止&…

VAE中的“变分”什么

写在前面 VAE&#xff08;Variational Autoencoder&#xff09;&#xff0c;中文译为变分自编码器。其中AE&#xff08;Autoencoder&#xff09;很好理解。那“变分”指的是什么呢?—其实是“变分推断”。变分推断主要用在VAE的损失函数中&#xff0c;那变分推断是什么&#x…