当前位置: 首页 > news >正文

springboot3 exception 全局异常处理入门与实战

Exception 项目

https://gitee.com/supervol/loong-springboot-study

(记得给个start,感谢)

Exception 概述

        在 Spring Boot 3 应用开发中,全局异常处理是保证系统稳定性和用户体验的重要环节。它能统一捕获、处理应用中抛出的各类异常,避免原始错误信息直接暴露给用户,同时提供标准化的响应格式。

Exception 核心

1. 核心作用

  1. 统一响应格式:无论发生何种异常,都返回结构一致的响应(如包含状态码、错误信息、时间戳等),便于前端解析。
  2. 隐藏敏感信息:避免将堆栈信息、数据库路径等敏感信息直接返回给客户端。
  3. 简化异常处理:无需在每个 Controller 中重复编写 try-catch 逻辑,降低代码冗余。
  4. 便于问题排查:集中记录异常日志,统一管理异常处理策略。

2. 核心注解

        Spring Boot 3 通过 AOP(面向切面编程)实现全局异常处理,核心注解如下:

注解作用
@RestControllerAdvice全局异常处理的 "切面类" 注解,结合了@ControllerAdvice@ResponseBody,确保返回 JSON 格式响应。
@ExceptionHandler标记在方法上,指定该方法处理的异常类型(如@ExceptionHandler(BusinessException.class))。
@ResponseStatus配合@ExceptionHandler使用,指定异常处理后返回的 HTTP 状态码(如 400、500)。

Exception 示例

        请参考项目地址中 springboot-configuration/springboot-configuration-exception 模块代码。

Exception 实现

1. 定义统一响应体

        首先创建一个标准化的响应类,确保成功 / 失败响应格式一致:

import lombok.Data;
import java.time.LocalDateTime;@Data
public class Result<T> {// 状态码(如200成功,500系统错误,400业务异常)private Integer code;// 响应消息private String message;// 响应数据(成功时返回)private T data;// 时间戳private LocalDateTime timestamp;// 成功响应(带数据)public static <T> Result<T> success(T data) {Result<T> result = new Result<>();result.setCode(200);result.setMessage("操作成功");result.setData(data);result.setTimestamp(LocalDateTime.now());return result;}// 失败响应(带错误信息)public static <T> Result<T> fail(Integer code, String message) {Result<T> result = new Result<>();result.setCode(code);result.setMessage(message);result.setTimestamp(LocalDateTime.now());return result;}
}
2. 定义自定义业务异常

        实际开发中,业务逻辑异常(如 "用户不存在"、"余额不足")需要与系统异常区分,因此通常定义自定义异常:

// 自定义业务异常(继承RuntimeException,无需强制try-catch)
public class BusinessException extends RuntimeException {// 异常状态码(可自定义,如400表示参数错误)private Integer code;// 构造方法(消息+状态码)public BusinessException(String message, Integer code) {super(message);this.code = code;}// 构造方法(消息+状态码+原始异常)public BusinessException(String message, Integer code, Throwable cause) {super(message, cause);this.code = code;}// getterpublic Integer getCode() {return code;}
}
3. 实现全局异常处理器

        通过@RestControllerAdvice定义全局异常处理类,使用@ExceptionHandler处理不同类型的异常:

import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;@Slf4j
@RestControllerAdvice // 全局异常处理切面
public class GlobalExceptionHandler {// 处理自定义业务异常@ExceptionHandler(BusinessException.class)public Result<Void> handleBusinessException(BusinessException e) {log.error("业务异常: {}", e.getMessage(), e); // 记录异常日志return Result.fail(e.getCode(), e.getMessage());}// 处理参数校验异常(如@Valid注解触发的校验失败)@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(HttpStatus.BAD_REQUEST) // 返回400状态码public Result<Void> handleMethodArgumentNotValidException(MethodArgumentNotValidException e) {BindingResult bindingResult = e.getBindingResult();// 提取第一个错误信息(也可返回所有错误)FieldError firstError = bindingResult.getFieldError();String errorMsg = firstError != null ? firstError.getDefaultMessage() : "参数校验失败";log.error("参数校验异常: {}", errorMsg, e);return Result.fail(400, errorMsg);}// 处理404异常(需在配置中开启:spring.mvc.throw-exception-if-no-handler-found=true)@ExceptionHandler(NoHandlerFoundException.class)@ResponseStatus(HttpStatus.NOT_FOUND) // 返回404状态码public Result<Void> handleNoHandlerFoundException(NoHandlerFoundException e) {log.error("资源不存在: {}", e.getRequestURL(), e);return Result.fail(404, "请求的资源不存在");}// 处理所有未捕获的异常(兜底处理)@ExceptionHandler(Exception.class)@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) // 返回500状态码public Result<Void> handleException(Exception e) {log.error("系统异常: ", e); // 记录完整堆栈,便于排查return Result.fail(500, "系统繁忙,请稍后再试");}
}
4. 配置支持 404 异常捕获

        默认情况下,Spring Boot 不会将 404(资源不存在)视为异常抛出,需在application.yml中添加配置:

spring:mvc:throw-exception-if-no-handler-found: true # 找不到接口时抛出NoHandlerFoundExceptionweb:resources:add-mappings: false # 关闭默认静态资源映射(避免静态资源路径干扰)

Exception 注意

        当多个@ExceptionHandler方法都能处理某一异常时,Spring Boot 会按 "更具体的异常优先" 原则匹配。例如:@ExceptionHandler(BusinessException.class) 优先于 @ExceptionHandler(Exception.class)(因为BusinessExceptionException的子类)。实践注意事项:

  1. 日志记录:异常处理时务必记录日志(尤其是Exception兜底方法),建议使用log.error("错误信息", e)记录完整堆栈。
  2. 区分异常类型:业务异常、参数异常、系统异常应分开处理,返回不同的状态码和消息。
  3. 避免吞掉异常:不要在异常处理器中捕获异常后不做任何处理(如try-catch后不返回响应)。
  4. 自定义 HTTP 状态码:通过@ResponseStatus注解或ResponseEntity灵活设置响应的 HTTP 状态码(如 401 未授权、403 禁止访问)。

Exception 总结

        Spring Boot 3 的全局异常处理通过@RestControllerAdvice@ExceptionHandler实现,核心是将分散的异常处理逻辑集中管理,提供统一、安全、易维护的异常响应机制。实际开发中,需结合自定义异常、统一响应体和细致的日志记录,打造健壮的异常处理体系。

http://www.dtcms.com/a/395074.html

相关文章:

  • spring简单入门和项目创建
  • lVS 负载均衡技术
  • 【论文阅读】OpenDriveVLA:基于大型视觉语言动作模型的端到端自动驾驶
  • Redis 缓存更新策略与热点数据识别
  • 新手小白——Oracle新建表完成题目
  • 如何让百度快速收录网页如何让百度快速收录网页的方法
  • Bugku-1和0的故事
  • 微硕WINSOK N+P MOSFET WSD3067DN56,优化汽车智能雨刷系统
  • DeviceNet 转 Profinet:西门子 S7 - 1500 PLC 与欧姆龙伺服电机在汽车焊装生产线夹具快速切换定位的通讯配置案例
  • 探索鸿蒙应用开发:构建一个简单的音乐播放器
  • 人脸识别(具体版)
  • 4.10 顶点光源
  • 深度学习---PyTorch 神经网络工具箱
  • 第九篇:静态断言:static_assert进行编译期检查
  • 第10讲 机器学习实施流程
  • tablesample函数介绍
  • 机器学习-单因子线性回归
  • android pdf框架-14,mupdf重排
  • 借助VL模型实现一个简易的pdf书签生成工具
  • 78-数据可视化-折线图
  • 静默安装 Oracle Database 21c on CentOS 7.9
  • DINOv3详解+实际下游任务模型使用细节(分割,深度,分类)+ Lora使用+DINOv1至v3区别变换分析(可辅助组会)
  • Linux编译SRS并测试RTMP流
  • 【完整源码+数据集+部署教程】遥感温室图像分割系统: yolov8-seg-slimneck
  • Apache 生产环境操作与 LAMP 搭建指南
  • 11种数据库类型详解:数据库分关系数据库、非关系数据库、时序数据库、向量数据库等
  • UVa12180/LA4300 The Game
  • Kafka 核心原理、架构与实践指南
  • Tesollo展示灵巧手自动化精准测量系统
  • 11MySQL触发器实战:用户操作日志审计系统