SpringBoot中的统一异常处理示例代码

 更新时间:2026年03月20日 15:28:30   作者:新绿MEHO  
本文给大家介绍SpringBoot中的统一异常处理示例代码,本文结合实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧

统一异常处理

统⼀异常处理使⽤的是 @ControllerAdvice + @ExceptionHandler 来实现的,
@ControllerAdvice 表⽰控制器通知类, @ExceptionHandler 是异常处理器,两个结合表
⽰当出现异常的时候执⾏某个通知,也就是执⾏某个方法事件。

代码示例

ExceptionAdvice 

接⼝返回为数据时, 需要加 @ResponseBody 注解!!!

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 springbook.model.Result;
@Slf4j
@ResponseBody
@ControllerAdvice
public class ExceptionAdvice {
    @ExceptionHandler
    public Result handlerException(Exception e){
        log.error("发生异常, e: {}", e);
        return Result.fail("内部错误");
    }
    @ExceptionHandler
    public Result handlerException(NullPointerException e){
        log.error("发生异常, e:", e);
        return Result.fail("发生空指针异常");
    }
    @ExceptionHandler
    public Result handlerException(ArithmeticException e){
        log.error("发生异常, e:", e);
        return Result.fail("发生算术异常");
    }
}

 Result

import lombok.Data;
import springbook.enums.ResultStatus;
@Data
public class Result<T> {
    private ResultStatus code; 
    private String errMsg; //错误信息, 如果业务成功, 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 resultStatus, String msg){
        Result result = new Result<>();
        result.setCode(resultStatus);
        result.setErrMsg(msg);
        return result;
    }
}

TestController

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;
    }
}

运行结果 

t1的运行结果:

t2的运行结果:

t3的运行结果:

问题

我们知道,ArithmeticException和NullPointerException都属于RuntimeException,同时RuntimeException又属于Exception。

那么为什么同时有处理ArithmeticException和Exception的方法时,针对ArithmeticException异常,会调用处理ArithmeticException异常的方法而不是调用处理Exception异常的方法?

那么为什么同时有处理NullPointerException和Exception的方法时,针对NullPointerException异常,会调用处理NullPointerException异常的方法而不是调用处理Exception异常的方法?

结合源码了解问题源头 

下面通过Debug的方式,结合源码来剖析为什么会出现上面的问题。

以上面代码的访问test/t1路径下方法导致ArithmeticException异常为例:

经过Debug,我了解到,处理异常会走到下图所示的ExceptionHandlerMethodResolver类里面的getMapperMethod()方法:

在刚进入该方法的时候,经过第一个黄色框内代码的处理后,会把当前具有处理异常的方法结合当前发生的异常进行匹配,最终匹配到两个合适类型的异常,分别是Exception异常和ArithmeticException异常:

但是在经过第二个黄色框内的代码处理后,会对刚刚匹配到的异常进行排序,根据异常的深度进行排序,并返回深度最浅的异常(即返回最合适的异常)。

经过第二个黄色框内的代码处理后,matches里面的内容顺序发生变动:

此时,我们就知道了为什么同时有处理ArithmeticException和Exception的方法时,针对ArithmeticException异常,会调用处理ArithmeticException异常的方法而不是调用处理Exception异常的方法;以及为什么同时有处理NullPointerException和Exception的方法时,针对NullPointerException异常,会调用处理NullPointerException异常的方法而不是调用处理Exception异常的方法。

优点

1. 提高用户体验
        友好的错误信息:通过统一异常处理,可以为前端或其他服务提供一致的、易于理解的错误信息,而不是直接暴露后端的堆栈跟踪或技术细节,从而提升用户体验。
        避免敏感信息泄露:统一处理可以避免在异常响应中不小心泄露敏感信息,如数据库表结构、内部实现细节等。
2. 业务逻辑和异常处理逻辑解耦
        代码结构清晰:将异常处理逻辑从业务逻辑中分离出来,使得业务代码更加专注于业务逻辑的实现,而异常处理代码则专注于异常的捕获、处理和响应。
        易于维护:当需要修改异常处理逻辑时,只需在统一异常处理类中修改,而无需在多个业务代码中逐一修改,降低了维护成本。
3. 减少冗余代码
        避免重复编写:在传统的Java开发中,异常处理通常是分散在代码的各个部分中的。而使用统一异常处理可以避免在每个可能抛出异常的地方编写重复的异常处理代码。
        提高代码复用性:通过定义全局的异常处理类,可以实现对多种异常的统一处理,提高代码的复用性。
4. 便于代码风格统一
        风格一致:统一异常处理有助于保持代码风格的一致性,使得整个项目的代码更加规范、整洁。
        提升可读性:对于其他开发者来说,阅读和理解统一异常处理的代码也更为容易。
5. 便于异常监控和日志记录
        集中监控:通过统一异常处理,可以更容易地实现对异常情况的集中监控和统计,为后续的故障排查和性能优化提供依据。
        详细日志:在异常处理过程中,可以记录详细的异常信息和上下文信息,便于后续的日志分析和问题定位。

到此这篇关于SpringBoot中的统一异常处理示例代码的文章就介绍到这了,更多相关SpringBoot统一异常处理内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • java基于swing实现的连连看代码

    java基于swing实现的连连看代码

    这篇文章主要介绍了java基于swing实现的连连看代码,包含了游戏中涉及的事件处理与逻辑功能,需要的朋友可以参考下
    2014-11-11
  • += 和 ++ 操作符区别简单介绍

    += 和 ++ 操作符区别简单介绍

    这篇文章主要介绍了+= 和 ++ 操作符区别简单介绍的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • Java 在PDF中添加条形码的两种方法

    Java 在PDF中添加条形码的两种方法

    本文就将通过使用Java程序来演示如何在PDF文档中添加Codebar、Code128A和Code39条形码。通过实例代码给大家讲解的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-03-03
  • SchedulingConfigurer实现动态定时,导致ApplicationRunner无效解决

    SchedulingConfigurer实现动态定时,导致ApplicationRunner无效解决

    这篇文章主要介绍了SchedulingConfigurer实现动态定时,导致ApplicationRunner无效的解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-05-05
  • ireport数据表格报表的简单使用

    ireport数据表格报表的简单使用

    这篇文章给大家介绍了如何画一个报表模板,这里介绍下画表格需要用到的组件,文中通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2021-10-10
  • Spring实现声明式事务的方法详解

    Spring实现声明式事务的方法详解

    这篇文章主要介绍了Spring实现声明式事务的方法详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-01-01
  • Java多线程之间日志traceId传递方式

    Java多线程之间日志traceId传递方式

    这篇文章主要介绍了Java多线程之间日志traceId传递方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-08-08
  • Java泛型枚举Annotation接口详细解读与Eclipse发展

    Java泛型枚举Annotation接口详细解读与Eclipse发展

    这篇文章主要给大家介绍了关于Java中方法使用的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08
  • SpringBoot集成Nacos的实战完全指南

    SpringBoot集成Nacos的实战完全指南

    Nacos 作为阿里巴巴开源的一站式微服务管理平台,已成为 Spring Cloud Alibaba 生态的核心组件,本文基于 Spring Boot 3.x + Nacos 2.x 最新版本,系统讲解 Nacos 的安装部署、配置中心、服务发现等核心功能,并提供生产级最佳实践方案,有需要的小伙伴可以了解下
    2026-02-02
  • Docker环境下Spring Boot应用内存飙升分析与解决场景分析

    Docker环境下Spring Boot应用内存飙升分析与解决场景分析

    当运行一个Spring Boot项目时,如果未设置JVM内存参数,Spring Boot默认会采用JVM自身默认的配置策略,接下来通过本文给大家介绍Docker环境下Spring Boot应用内存飙升分析与解决方法,需要的朋友参考下吧
    2021-08-08

最新评论