原代码:

package com.weiyu.exception;import com.weiyu.pojo.Result;
import com.weiyu.utils.ErrorFileResponseUtils;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;/*** 全局异常处理器*/
@RestControllerAdvice
@SuppressWarnings("unused") // 使用这个注解来抑制警告 或 使用 @Component
@Slf4j
public class GlobalExceptionHandler {/*** 处理防抖异常(同时支持普通请求和文件下载请求)*/@ExceptionHandler(DebounceException.class)public Object handleDebounceException(DebounceException e, HttpServletRequest request) {// 文件下载请求返回错误文件if (ErrorFileResponseUtils.isFileDownloadRequest(request)) {return ErrorFileResponseUtils.createErrorFileResponse(e);}// 2. 普通请求返回 json 错误return Result.error(e.getMessage(), e.getCode());}/*** 处理其他所有异常*/@ExceptionHandler(Exception.class)public Object handleException(Exception e, HttpServletRequest request) {// ❌ 禁止使用 printStackTrace 在控制台输出异常的详细堆栈跟踪信息// e.printStackTrace();// ✅ 规范做法:使用日志框架记录异常(参数 e 包含异常的详细堆栈跟踪信息)log.error("异常错误 {}", e.getMessage(), e);// 文件下载请求返回错误文件if (ErrorFileResponseUtils.isFileDownloadRequest(request)) {String message = StringUtils.hasLength(e.getMessage()) ? e.getMessage() : "下载文件失败";return ErrorFileResponseUtils.createErrorFileResponse(message, HttpStatus.INTERNAL_SERVER_ERROR);}// 普通请求返回 json 错误return Result.error(StringUtils.hasLength(e.getMessage()) ? e.getMessage() : "操作失败", 500);}
}

以下是对提供的Spring Boot全局异常处理代码的详细注释和作用说明:

package com.weiyu.exception;import com.weiyu.pojo.Result;                   // 自定义的统一响应对象
import com.weiyu.utils.ErrorFileResponseUtils;  // 处理错误文件响应的工具类
import jakarta.servlet.http.HttpServletRequest; // 获取HTTP请求信息
import lombok.extern.slf4j.Slf4j;               // Lombok日志注解
import org.springframework.http.HttpStatus;     // HTTP状态码枚举
import org.springframework.util.StringUtils;    // Spring字符串工具类
import org.springframework.web.bind.annotation.ExceptionHandler;        // 异常处理器注解
import org.springframework.web.bind.annotation.RestControllerAdvice;    // 控制器增强注解/*** 全局异常处理器* 作用:集中处理整个应用程序中控制器层抛出的异常*/
@RestControllerAdvice       // 组合注解:包含 @ControllerAdvice + @ResponseBody,使返回值自动转为JSON
@SuppressWarnings("unused") // 使用这个注解来抑制警告 或 使用 @Component
@Slf4j                      // 自动生成日志对象
public class GlobalExceptionHandler {/*** 处理防抖异常(DebounceException),同时支持普通请求和文件下载请求* 适用场景:当检测到重复/频繁请求时抛出的自定义异常** @param e 捕获的防抖异常对象* @param request HTTP请求对象* @return 根据请求类型返回不同响应:文件下载请求返回错误文件,普通请求返回JSON错误信息*/@ExceptionHandler(DebounceException.class)  // 指定处理的异常类型public Object handleDebounceException(DebounceException e, HttpServletRequest request) {// 1. 检查是否为文件下载请求if (ErrorFileResponseUtils.isFileDownloadRequest(request)) {// 生成包含错误信息的文件响应(如txt)return ErrorFileResponseUtils.createErrorFileResponse(e);}// 2. 普通请求返回统一JSON错误格式return Result.error(e.getMessage(), e.getCode());}/*** 处理所有其他未明确指定的异常(顶级异常处理器)* 作用:作为异常处理的兜底方案,确保所有异常都被处理*/@ExceptionHandler(Exception.class)  // 捕获所有未被处理的异常public Object handleException(Exception e, HttpServletRequest request) {// ❌ 禁止使用 printStackTrace 在控制台输出异常的详细堆栈跟踪信息// e.printStackTrace();// ✅ 规范日志记录:使用日志框架记录完整异常堆栈(参数 e 包含异常的详细堆栈跟踪信息)log.error("异常错误 {}", e.getMessage(), e);    // 记录错误消息和详细堆栈跟踪信息// 1. 处理文件下载请求的异常if (ErrorFileResponseUtils.isFileDownloadRequest(request)) {// 确保错误消息不为空,使用默认消息兜底String message = StringUtils.hasLength(e.getMessage()) ? e.getMessage() : "下载文件失败";// 生成包含错误信息的文件响应,使用500状态码return ErrorFileResponseUtils.createErrorFileResponse(message, HttpStatus.INTERNAL_SERVER_ERROR);}// 2. 普通请求的异常处理return Result.error(StringUtils.hasLength(e.getMessage()) ? e.getMessage() : "操作失败",    // 消息处理500 // 统一返回500服务器错误状态码);}
}

核心作用解析:

  1. 统一异常处理

    • 通过@RestControllerAdvice注解实现全局拦截控制器层抛出的异常

    • 避免在每个Controller中重复编写异常处理代码

  2. 差异化响应处理

  3. 自定义异常处理(DebounceException)

    • 专门处理防抖逻辑相关的异常

    • 使用异常自带的错误码和消息(e.getCode()e.getMessage()

    • 示例场景:限制用户频繁提交表单/重复请求

  4. 全局兜底处理(Exception.class)

    • 捕获所有未被特殊处理的异常

    • 关键安全实践:禁止使用printStackTrace()(会暴露敏感信息)

    • 正确做法:通过日志框架记录完整堆栈(log.error("msg", e)

  5. 空消息安全处理

    • 使用StringUtils.hasLength()检查消息有效性

    • 提供默认友好提示("操作失败"/"下载文件失败")

    • 避免返回空错误信息导致客户端解析失败

  6. HTTP状态码管理

    • 普通请求:返回500错误码(通过Result对象封装)

    • 文件请求:设置HTTP状态为500(HttpStatus.INTERNAL_SERVER_ERROR

最佳实践亮点:

  1. 日志规范

    java

    // 错误做法(禁止): 暴露堆栈到控制台
    // e.printStackTrace(); // 正确做法(采用): 日志系统记录完整错误
    log.error("异常详细信息: {}", e.getMessage(), e);
  2. 扩展性设计

    • 通过ErrorFileResponseUtils工具类分离文件处理逻辑

    • 便于后续扩展其他文件类型处理

  3. 防御式编程

    • e.getMessage()进行空值检测

    • 使用工具类方法判断请求类型(isFileDownloadRequest

  4. 响应标准化

    • 统一使用Result对象返回JSON格式错误

    json

    // 响应示例
    {"code": 500,"msg": "操作失败","data": null
    }

该实现有效解决了Spring Boot应用中的三个核心异常处理问题:
① 异常类型差异化处理 ② 响应形式自适配(JSON/文件) ③ 生产环境安全的错误日志记录

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

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

相关文章

FHE技术将彻底改变在线隐私保护方式

1. 在线隐私的简史 互联网刚刚诞生时,所有的内容都是未加密的。人们通过一个特定的地址访问网站,这个地址以“HTTP”开头。当时,这并不是什么大问题,因为人们在线访问的都是内容,而这些内容本身已经是公开的。但随着电…

Cursor配置Java环境、创建Spring Boot项目

一:配置JDK和Maven cursor默认会读取环境变量JAVA_HOME和MAVEN_HOME,如果没有配置去找默认路径~/.m2/settings.xml也可以手动指定:Ctrl Shift P 输入"Preferences:Open User Settings(JSON)"打开settings.json文件,然…

win11添加无线显示器(两个笔记本实现双屏)

前置条件: 两个笔记本要要支持无线显示器,支持蓝牙; 1、自己重装的win11系统,首先根据网上说明进去的时候,红色显示无无线投屏; 2、安装网上操作,查看自己电脑是否支持无线投屏(是支…

【MAC技巧】Bash/Zsh切换失败的故障排除

【MAC技巧】Bash/Zsh切换失败的故障排除 Troubleshooting to Failure " chsh: no changes made" By JacksonML 在Mac电脑中,终端(Terminal)是常用的命令行工具,对开发和运维至关重要。 依照苹果电脑的系统软件迭代,终端中存有B…

卷积神经网络-卷积的分类

卷积的定义卷积是图像处理中最核心的操作之一,其本质是通过卷积核(滤波器)与图像进行滑动窗口计算(像素值乘积之和),实现对图像特征的提取、增强或抑制。一、二维卷积--针对二维矩阵进行处理1.1单通道见得最…

全网首发:使用GIT下载时崩溃退出,是因为机械硬盘

前面有几篇文章,说是GIT下载会退出。开始以为是虚拟机问题。把家里的虚拟机复制到公司,照样崩溃。后来认为是内存不足。昨天在家里下载代码,也崩溃退出。心里觉得奇怪,试了一次,还是退出。差别在哪里?之前是…

YAML 自动化用例中 GET vs POST 请求的参数写法差异

GET 请求:用 params 传参(附加在 URL 上) config:name: "GET 查询用户信息"base_url: "https://api.example.com"teststeps:- name: "根据 userId 查询用户信息"request:method: GETurl: /api/user/detailpara…

使用 SeaTunnel 建立从 MySQL 到 Databend 的数据同步管道

SeaTunnel 是一个非常易用、超高性能的分布式数据集成平台,支持实时海量数据同步。 每天可稳定高效地同步数百亿数据,已被近百家企业应用于生产,在国内较为普及。 Databend 是一款开源、弹性、低成本,基于对象存储也可以做实时分…

linux服务器换ip后客户端无法从服务器下载数据到本地问题处理

服务器换ip后客户端无法从服务器下载数据到本地,根据上图提示,让用户清理下~/.ssh/known_hosts文件,下载恢复正常。

从0到1实现Shell!Linux进程程序替换详解

目录从0到1实现Shell!Linux进程程序替换详解 🚀引言:为什么进程需要"变身术"?一、程序替换:进程的"换衣服"魔法 🔄1.1 什么是程序替换?1.2 程序替换的原理:内存…

暑期算法训练.2

目录 6.力扣 11.盛水最多的容器 6.1 题目解析: 6.2 算法思路: 6.2.1 暴力解法: 6.2.2 优化算法: 6.3 代码演示: ​编辑 6.4 总结反思: 7.力扣 611.有效的三角形个数 7.1 题目解析: 7.2…

华为OD 消消乐游戏

1. 题意 游戏规则:输入一个只包含英文字母的字符串,字符串中的两个字母如果相邻且相同,就可以消除。 在字符串上反复执行消除的动作,直到无法继续消除为止,此时游戏结束。 输出最终得到的字符串长度。 输入 输入原始…

小白学HTML,操作HTML文件篇(2)

目录 一、添加多媒体 1.添加网页图片 2.添加网页音频 3.添加网页视频 二、创建容器 1. 标签 2.布局 三、创建表格 1.表格标签 2.添加表格表头 3.添加表格标题 一、添加多媒体 在 HTML 网页中可以轻松地使用标签来添加图片、音频、视频等多媒体,而这些多媒体并…

微服务架构中实现跨服务的字段级权限统一控制

结合集中式权限管理、分布式上下文传递、动态策略执行等技术 ​​一、核心架构设计​​ ​​1. 分层控制模型​​ ​​网关层​​:统一校验用户身份与基础权限,拦截非法请求。 ​​服务层​​:基于用户权限动态过滤数据字段,实现业务级控制。 ​​策略中心​​:集中管理权…

【实现100个unity特效之27】使用unity的ShaderGraph实现一个带裁剪边缘光的裁剪效果(2d3d通用)

文章目录普通裁剪效果1、创建一个Lit Shader Graph2、ShaderGraph前置配置3、添加节点4、效果5、修改裁剪方向带边缘色的裁剪1、在裁剪的基础上添加裁剪边缘光2、边缘的亮度3、修改裁剪方向4、效果5、我们可以代码控制它的变化,如下2D3D游戏通用专栏推荐完结普通裁剪…

Android Scoped Storage适配完全指南

Android Scoped Storage适配完全指南关键词:Android、Scoped Storage、适配、存储权限、文件访问摘要:本文将全面介绍Android Scoped Storage的相关知识,从背景出发,详细解释核心概念,阐述其原理和架构,给出…

Typecho集成PHPMailer实现邮件订阅功能完整指南

文章目录 Typecho使用PHPMailer实现文章推送订阅功能详解 1. 背景与需求分析 1.1 为什么选择PHPMailer 1.2 功能需求 2. 环境准备与配置 2.1 安装PHPMailer 2.2 数据库设计 3. 核心功能实现 3.1 邮件服务封装类 3.2 订阅功能实现 3.2.1 订阅表单处理 3.2.2 确认订阅处理 3.3 文…

无线-二层组网-直接转发

文章目录无线二层组网直接转发🏡作者主页:点击! 🤖Datacom专栏:点击! ⏰️创作时间:2025年07月16日08点00分 无线二层组网 直接转发 本地转发中所有的沿途都需要配置对应VLAN的通过&#xff…

gin go-kratos go-zero框架对比

Gin、Go-Kratos 和 Go-Zero 是 Go 语言中三种常见的服务框架,它们在定位、设计理念、复杂度和适用场景上差异较大。下面我们从功能定位、设计理念、优劣对比、使用建议等维度进行深入对比。🧭 一句话总结框架定位Gin轻量级、高性能的 HTTP 路由框架Go-Kr…

4G模块 A7670发送英文短信到手机

命令说明ATi显示产品的标志信息 ATCIMI查询IMSI ATCICCID从SIM卡读取ICCID ATCGSN查询产品序列号 ATCPIN查询卡状态 ATCSQ查询信号强度 ATCGATT查询当前PS域状态 ATCREG查询GPRS注册状态 ATCEREG查询4G注册状态 ATCGPADDR查询PDP地址 ATCMGF选择短信格式 ATCMGS发送短信流程第一…