SpringBoot中@RestControllerAdvice @ExceptionHandler异常统一处理类失效原因分析

 更新时间:2024年01月23日 17:01:02   作者:MLJ.  
这篇文章主要介绍了SpringBoot中@RestControllerAdvice @ExceptionHandler异常统一处理类失效原因,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

项目原来的处理方式

在我的项目中,我原本只使用了 @ExceptionHandler 注解,并通过继承的方式实现了统一异常处理。

我创建了一个名为 BaseController 的父类,其中包含了以下代码:

public class BaseController {
 
    @ExceptionHandler(Exception.class)
    public RestResult handleException(Throwable e) {
        //定义异常处理的响应数据模型
        RestResult result = new RestResult();
        result.setSuccess(false);
        result.setData(e.getMessage());
        result.setErrorCode(500);
        e.printStackTrace();
        return result;
    }
}

然后,我让项目中需要统一异常管理的 @Controller 类都继承了 BaseController。

例如,我有一个名为 UserController 的控制器:

@RequestMapping("/user")
public class UserController extends BaseController {
    ···
}

通过这种方式,我成功实现了统一异常处理,但是这种方法需要让所有的 @Controller 类都继承BaseController,有些繁琐。

使用@RestControllerAdvice和@ExceptionHandler组合

后来,我在网上找到了使用 @RestControllerAdvice 和 @ExceptionHandler 组合的方法。

我创建了一个名为 GlobalExceptionHandler 的类,其中包含了以下代码:

@RestControllerAdvice
public class GlobalExceptionHandler {
 
    @ExceptionHandler(Exception.class)
    public RestResult handleException(Throwable e) {
        //定义异常处理的响应数据模型
        RestResult result = new RestResult();
        result.setSuccess(false);
        result.setData(e.getMessage());
        result.setErrorCode(500);
        e.printStackTrace();
        return result;
    }
}

遇到的问题描述

起初,我以为这种方法不会有什么问题。但是在测试过程中,我发现统一处理异常的方法一直没有被调用,即使我尝试了很多方法也没有解决。

直到我看到一个帖子提到,被 @RestControllerAdvice 标注的类必须单独放到一个文件夹中,我半信半疑地创建了一个名为 "a" 的文件夹,并将 GlobalExceptionHandler 类放进去后重新测试。

令我没想到的是,异常发生时确实跳转到了统一处理的方法中。

然后,我又将文件夹的名字改为 "exceptionHandler" 后重新测试,结果又无法跳转到统一处理的方法中。

此时我已经发现了问题所在。由于我将控制器代码放在了名为 "controller" 的文件夹中,一开始我将 "GlobalExceptionHandler" 类放到名为 "a"的文件夹,它在 "controller" 的首字母 "c" 上面;后来我我将 "GlobalExceptionHandler" 类放到以 "e" 开头的文件夹,它在 "controller" 的首字母 "c" 下面。

因此,这可能是由于 Spring Bean 加载顺序的问题。

解决

只需要在GlobalExceptionHandler类中添加@Order注解,以确保它优先加载就没问题了。

@Order(9999)
@RestControllerAdvice
public class GlobalExceptionHandler {
 
    @ExceptionHandler(Exception.class)
    public RestResult handleException(Throwable e) {
        //定义异常处理的响应数据模型
        RestResult result = new RestResult();
        result.setSuccess(false);
        result.setData(e.getMessage());
        result.setErrorCode(500);
        e.printStackTrace();
        return result;
    }
}

添加了 @Order 注解后,重新进行测试,问题就得到了解决。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring Cloud原理以及核心组件详解

    Spring Cloud原理以及核心组件详解

    这篇文章主要介绍了Spring Cloud原理以及核心组件详解,spring cloud有5个核心组件,文章中进行了一一的详细介绍,需要的朋友可以参考下
    2023-03-03
  • Springboot视图解析器ViewResolver使用实例

    Springboot视图解析器ViewResolver使用实例

    这篇文章主要介绍了Springboot视图解析器ViewResolver使用实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • Java8中Lambda表达式的理解与应用

    Java8中Lambda表达式的理解与应用

    Java8最值得学习的特性就是Lambda表达式和Stream API,如果有python或者javascript的语言基础,对理解Lambda表达式有很大帮助,下面这篇文章主要给大家介绍了关于Java8中Lambda表达式的相关资料,需要的朋友可以参考下
    2022-02-02
  • Java编程实现非对称加密的方法详解

    Java编程实现非对称加密的方法详解

    这篇文章主要介绍了Java编程实现非对称加密的方法,简单讲述了非对称加密的概念、原理,并结合实例形式分析了java实现DH加密解密、RSA加密解密、ElGamal加密等具体操作技巧,需要的朋友可以参考下
    2017-08-08
  • Java中设置JAVA_HOME无效的解决方法

    Java中设置JAVA_HOME无效的解决方法

    最近遇到一个问题,就是配置JAVA_HOME无效,不管怎么改,运行Java -version始终是最初的那个java版本,所以这篇文章主要给大家介绍了关于Java中设置JAVA_HOME无效的解决方法,需要的朋友可以参考借鉴,下面来一起看看吧。
    2017-09-09
  • vue验证码组件应用实例

    vue验证码组件应用实例

    今天小编就为大家分享一篇关于vue验证码组件应用实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • AsyncHttpClient ChannelPool线程池频道池源码流程解析

    AsyncHttpClient ChannelPool线程池频道池源码流程解析

    这篇文章主要为大家介绍了AsyncHttpClient ChannelPool线程池频道池源码流程解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • 如何使用Java 8中DateTimeFormatter类型转换日期格式详解

    如何使用Java 8中DateTimeFormatter类型转换日期格式详解

    这篇文章主要介绍了如何使用Java 8中DateTimeFormatter类型转换日期格式详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Spring超详细讲解面向对象到面向切面

    Spring超详细讲解面向对象到面向切面

    面向对象编程是一种编程方式,此编程方式的落地需要使用“类”和 “对象”来实现,所以,面向对象编程其实就是对 “类”和“对象” 的使用,面向切面编程,简单的说,就是动态地将代码切入到类的指定方法、指定位置上的编程思想就是面向切面的编程
    2022-08-08
  • 使用ShardingSphere-Proxy实现分表分库

    使用ShardingSphere-Proxy实现分表分库

    这篇文章介绍了使用ShardingSphere-Proxy实现分表分库的方法,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-02-02

最新评论