【实用知识】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,一经查实,立即删除!

相关文章

设计模式(二)

设计模式(二) 敏捷开发模式&#xff1a;Refactoring to Patterns 重构特点&#xff1a; 1. 静态 --------> 动态 1. 早绑定 -----------> 晚绑定 1. 继承 ----------> 组合 1. 编译时依赖 --------> 运行时依赖 1. 紧耦合 -------> 松耦合组件协作模式 通过…

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;那么在尝试远…

压力测试指南-压力测试中的性能瓶颈定位与优化

压力测试中的性能瓶颈定位与优化 在当今快速迭代的软件开发环境中&#xff0c;确保应用能够承受高并发访问和大规模数据处理变得至关重要。压力测试作为评估系统极限能力的关键手段&#xff0c;不仅能揭示潜在的性能问题&#xff0c;还能指导我们进行针对性的优化。本文将深入…

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

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

异次元v4.0

萌次元商城系统基于异次元店铺系统3.0 全新重构&#xff0c;历时两年精心打磨&#xff0c;初心不改。我们采用纯原生PHP打造了一款极具潜力的个人创业型商城系统。数据库底层经过对hyperf/database 的深度优化&#xff0c;感谢hyperf开发团队提供的强大ORM组件。模版渲染引擎采…

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

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

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

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

DevEco Studio的使用 习题答案<HarmonyOS第一课>

一、判断题 1. 如果代码中涉及到一些网络、数据库、传感器等功能的开发,均可使用预览器进行预览。 正确(True)错误(False) 错误(False)回答正确 2. module.json5文件中的deviceTypes字段中,配置了phone,tablet,2in1等多种设备类型,才能进行多设备预览。 正确(True)…

redis第152节答疑 redis源码分析String重要总结

redis的string类型&#xff0c;如果数字大于10000&#xff0c;就不去共享整数中去取&#xff0c;然后就变成了embstr或者raw&#xff0c;为什么不是new一个redisobject,并且编码为int 对于Redis的字符串类型&#xff08;String&#xff09;&#xff0c;当字符串表示的是一个整数…

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

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

15分钟学 Go 第 20 天:Go的错误处理

第20天&#xff1a;Go的错误处理 目标 学习如何处理错误&#xff0c;以确保Go程序的健壮性和可维护性。 1. 错误处理的重要性 在开发中&#xff0c;错误处理至关重要。程序在运行时可能会出现各种问题&#xff0c;例如文件未找到、网络连接失败等。正确的错误处理能帮助我们…

中间人攻击(https降级攻击)和iptables命令分析

中间人攻击 以下是一个简单的中间人攻击示例&#xff0c;结合 ARP 欺骗和流量修改&#xff1a; 1. 进行 ARP 欺骗 首先&#xff0c;使用 arpspoof 进行 ARP 欺骗&#xff0c;将受害者的流量重定向到攻击者的机器上&#xff1a; sudo arpspoof -i eth0 -t 172.29.144.50 172…

Electron调用nodejs的cpp .node扩展【安全】

Electron调用nodejs的cpp .node扩展【安全】 环境&#xff1a; electron: 30.1.1 nodejs: 20.14.0前言 Electron是一个非常流行的跨平台桌面应用框架&#xff0c;它允许开发者使用Web技术来创建原生应用。然而&#xff0c;当应用需要进行高性能计算或访问系统API时&#xff…

echarts5.2.2实现 水球图表

需求背景解决思路解决效果index.vue 需求背景 需要做一个水球echarts图表效果&#xff0c;却发现echarts5以上版本已移除liquidFill类型 echarts 图表集链接 解决思路 引入 echarts-liquidfill^3.1.0 解决效果 index.vue <!--/*** author: liuk* date: 2024-10-24* de…

SVN(Subversion)的介绍和使用

SVN&#xff08;Subversion&#xff09;介绍 SVN&#xff08;Subversion&#xff09;是一个开源的版本控制系统&#xff0c;用于跟踪和控制文件和目录的更改。与传统的版本控制系统如CVS不同&#xff0c;SVN支持原子提交&#xff0c;即一次提交包含多个文件的更改&#xff0c;…

【计网】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和…

3.swoole安装【Docker】

一、拉取最新 swoole 镜像 docker pull phpswoole/swoole二、第一次启动swoole容器 docker run --name swoole phpswoole/swoole 三、 拷贝配置文件 docker cp swoole:/var/www /docker/swoole四、 停止 swoole 容器 dcoker stop swoole五、 删除第一次启动的swoole容器 d…

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…