跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客GitHub 精选镜像AI 生图工具UI配色美学隐私政策关于联系
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Spring Boot 统一异常处理:实现、原理与最佳实践

Spring Boot 全局异常处理通过 @ControllerAdvice 和 @ExceptionHandler 实现,旨在解耦业务逻辑与错误处理。本文结合源码解析了异常匹配优先级机制,即子类异常优于父类异常被捕获。统一处理能提升用户体验,避免敏感信息泄露,并便于集中监控日志。代码示例展示了如何定义通用返回结构及针对不同异常类型(如空指针、算术异常)的精细化处理策略。

灵魂摆渡发布于 2026/3/27更新于 2026/7/2034 浏览
Spring Boot 统一异常处理:实现、原理与最佳实践

Spring Boot 全局异常处理机制

在 Spring Boot 应用中,统一异常处理是提升系统健壮性和用户体验的关键环节。通过 @ControllerAdvice 配合 @ExceptionHandler,我们可以集中捕获并处理控制器层抛出的异常,避免将原始堆栈信息直接暴露给前端。

核心实现

定义一个全局异常处理类时,需添加 @ControllerAdvice 注解标识为通知类,并在具体处理方法上使用 @ExceptionHandler 指定要处理的异常类型。若接口返回数据格式需要 JSON,务必确保类或方法上存在 @ResponseBody(或类级别使用 @RestController)。

异常处理器示例

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import com.example.model.Result;

@Slf4j
@RestControllerAdvice
public class ExceptionAdvice {

    @ExceptionHandler
    public Result handlerException(Exception e) {
        log.error("发生未知异常", e);
        return Result.fail("内部错误");
    }

    @ExceptionHandler(NullPointerException.class)
    public Result handlerException(NullPointerException e) {
        log.error("发生空指针异常", e);
        return Result.fail("参数为空");
    }

    @ExceptionHandler(ArithmeticException.class)
    public Result handlerException(ArithmeticException e) {
        log.error("发生算术异常", e);
        return Result.fail("计算错误");
    }
}

统一返回结构

为了规范响应格式,建议封装通用的 Result 对象:

import lombok.Data;
import com.example.enums.ResultStatus;

@Data
public class Result<T> {
    private ResultStatus code;
    private String errMsg;
    private T data;

    public static <T> Result success(T data) {
        Result result = new Result<>();
        result.setCode(ResultStatus.SUCCESS);
        result.setData(data);
        return result;
    }

    public static Result fail(String msg) {
        Result result = new Result<>();
        result.setCode(ResultStatus.FAIL);
        result.setErrMsg(msg);
        return result;
    }

    public static Result fail(ResultStatus status, String msg) {
        Result result = new Result<>();
        result.setCode(status);
        result.setErrMsg(msg);
        return result;
    }
}

异常匹配优先级源码解析

在实际开发中,我们常遇到一个问题:当同时存在处理父类异常(如 Exception)和子类异常(如 ArithmeticException)的方法时,系统究竟会调用哪一个?

以访问 /test/t1 触发除零异常为例,我们可以通过调试模式深入 ExceptionHandlerMethodResolver 类的 getMapperMethod 方法来观察流程。

系统首先会收集当前上下文中所有能处理该异常类型的候选方法。对于 ArithmeticException,由于它既是 RuntimeException 的子类,也是 Exception 的子类,因此 handlerException(Exception) 和 handlerException(ArithmeticException) 都会被初步匹配到。

关键在于后续的排序逻辑。框架会根据异常的层级深度进行排序,优先选择最具体的异常类型。也就是说,子类异常的处理方法优先级高于父类异常。经过排序后,matches 集合中顺序发生变化,最终返回深度最浅(即最具体)的异常处理器。

这就解释了为什么针对 ArithmeticException 会调用专门的方法,而不是通用的 Exception 处理方法。同理,NullPointerException 也会优先于 Exception 被捕获。

业务价值

采用统一异常处理方案主要有以下几方面优势:

提升用户体验与安全性 通过统一封装,可以为前端提供一致且友好的错误提示,避免直接暴露后端堆栈跟踪或技术细节,防止敏感信息泄露。

解耦业务逻辑 将异常处理从业务代码中剥离,使 Controller 更专注于业务流转。当处理策略变更时,只需修改全局配置,降低了维护成本。

便于监控与日志 集中处理使得异常统计和日志记录更加容易,有助于快速定位故障根源并进行性能优化。同时,统一的代码风格也提升了项目的可读性。

测试验证

以下是一个简单的测试控制器,用于触发不同类型的异常:

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/test")
@RestController
public class TestController {

    @RequestMapping("/t1")
    public String t1() {
        int result = 10 / 0;
        return "string";
    }

    @RequestMapping("/t2")
    public Integer t2() {
        String str = null;
        System.out.println(str.length());
        return 1;
    }

    @RequestMapping("/t3")
    public Boolean t3() {
        Integer[] integers = new Integer[]{1, 2, 3, 4};
        System.out.println(integers[5]);
        return true;
    }
}

运行上述接口,控制台日志会记录对应的异常信息,而前端接收到的则是经过 Result 封装的标准响应。这种机制确保了无论底层抛出何种异常,上层交互始终稳定可控。

目录

  1. Spring Boot 全局异常处理机制
  2. 核心实现
  3. 异常处理器示例
  4. 统一返回结构
  5. 异常匹配优先级源码解析
  6. 业务价值
  7. 测试验证
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Python调用AI翻译API:requests封装最佳实践
  • NASA 火星任务软件测试:AIGC 模拟外星环境攻击
  • 分治算法实战:快速排序与归并排序
  • ChatMed 开源中文医疗大模型介绍与对比分析
  • 利用 AIGC 技术生成古诗意境图的方法与实践
  • 通义万相 2.1 在 AIGC 中的应用与部署实践
  • AndroidGen-Llama-3-70B:零标注自主操控安卓应用的大模型实践
  • 2024 年大模型学习路线:从数学基础到微调实战
  • LeetCode 原地复写零:双指针与逆向填充的 O(n) 解法
  • 5 款开源 PPT 生成大模型实测:ChatGPT 与文心一言等技术对比
  • 5 款主流 AI 代码生成工具实测:DeepSeek-Coder 在测试场景下的优势分析
  • Stable Diffusion 优雅 Prompt 编写指南
  • GitHub Trending AI Top3 项目解析与上手指南
  • Windows 环境 LLaMA-Factory 本地部署教程:从零搭建大模型工具链
  • C/C++数字与字符串互相转换
  • OpenClaw 配置与 QQ 机器人接入指南
  • Python 布尔类型详解:真值规则与逻辑运算实战
  • VSCode Copilot 接入智谱 GLM-5.1 大模型配置指南
  • Git 核心原理与基础操作详解 (上)
  • Windows Git 安装配置指南:避坑与最佳实践 (2025 版)

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online