SpringBoot自定义全局异常处理器的问题总结

 更新时间:2024年01月30日 16:28:15   作者:木子dn  
Springboot框架提供两个注解帮助我们十分方便实现全局异常处理器以及自定义异常,处理器会优先处理更具体的异常类型,如果没有找到匹配的处理器,那么它会寻找处理更一般异常类型的处理器,本文介绍SpringBoot自定义全局异常处理器的问题,一起看看吧

一、介绍

Springboot框架提供两个注解帮助我们十分方便实现全局异常处理器以及自定义异常

  • @ControllerAdvice@RestControllerAdvice(推荐)
  • @ExceptionHandler

二、实现

1. 定义全局异常处理器

定义GlobalExceptionHandler类,拦截所有异常。
@RestControllerAdvice注解使得你可以在GlobalExceptionHandler 中处理异常,@ExceptionHandle注解用于将指定异常绑定到处理的函数上。如下使用@ExceptionHandler(Exception.class)即对所有异常进行捕获处理。

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestErrorResponse exception(Exception e){
        //record log
        log.error("系统异常{}", e.getMessage(),e);
        //decode errorException
        String errMessage = "系统异常";
        return new RestErrorResponse(errMessage);
    }
}
@Data
@AllArgsConstructor
public class RestErrorResponse implements Serializable {
    private String errMessage;
}

事实上,写到这里已经可以用了,RestErrorResponse 用来承载错误信息到前端,因为@RestControllerAdvice已经包含了@ResponseBody

2. 自定义异常类

继承RuntimeException 异常类写一个自定义的异常类。这么做主要是能够使用自定义的枚举类来更优雅的抛出错误。

@Data
public class XueChengPlusException extends RuntimeException {
    private String errMessage;
    public XueChengPlusException() {
        super();
    }
    public XueChengPlusException(String errMessage) {
        super(errMessage);
        this.errMessage = errMessage;
    }
    public static void cast(CommonError commonError){
        throw new XueChengPlusException(commonError.getErrMessage());
    }
    public static void cast(String errMessage){
        throw new XueChengPlusException(errMessage);
    }
}
@Getter
public enum CommonError {
    UNKOWN_ERROR("执行过程异常,请重试。"),
    PARAMS_ERROR("非法参数"),
    OBJECT_NULL("对象为空"),
    QUERY_NULL("查询结果为空"),
    REQUEST_NULL("请求参数为空");
    private String errMessage;
    private CommonError( String errMessage) {
        this.errMessage = errMessage;
    }
}

同时,对于GlobalExceptionHandler 也要做一些修改,一方面处理自定义异常,另一方处理其余异常。

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    @ExceptionHandler(XueChengPlusException.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestErrorResponse customException(XueChengPlusException e){
        //record log
        log.error("系统异常{}", e.getErrMessage(),e);
        //decode errorException
        String errMessage = e.getErrMessage();
        return new RestErrorResponse(errMessage);
    }
    @ExceptionHandler(Exception.class)
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public RestErrorResponse exception(Exception e){
        //record log
        log.error("系统异常{}", e.getMessage(),e);
        //decode errorException
        String errMessage = CommonError.UNKOWN_ERROR.getErrMessage();
        return new RestErrorResponse(errMessage);
    }
}

三、使用

在程序中任意地方抛出异常,controllerservicedao层都可以,比如

throw new RuntimeException("价格不能为空且必须大于0");

这时走的就是

@ExceptionHandler(Exception.class)
    public RestErrorResponse exception(Exception e)

除此之外,可以这样抛出自定义异常,比如

XueChengPlusException.cast(CommonError.PARAMS_ERROR);
XueChengPlusException.cast("其他的消息");
throw new XueChengPlusException(CommonError.OBJECT_NULL.getErrMessage());
throw new XueChengPlusException("其他的消息");

这时走的就是

@ExceptionHandler(XueChengPlusException.class)
    public RestErrorResponse customException(XueChengPlusException e)

四、疑问

Q:疑问,XueChengPlusException异常类继承自RuntimeException ,而RuntimeException 继承自Exception,为什么触发customException而不是exception?

在这个全局异常处理器中,当抛出一个XueChengPlusException异常时,它会被customException(XueChengPlusException e)方法处理,而不是exception(Exception e)方法。

这是因为Spring框架的异常处理机制会优先匹配最具体的异常类型。在您的代码中,XueChengPlusExceptionRuntimeException(以及Exception)的子类,因此它更具体。所以,当抛出一个XueChengPlusException异常时,Spring会优先调用处理XueChengPlusException的方法,而不是处理Exception的方法。

这种行为确实表明全局异常处理器有一定的优先级和覆盖逻辑。具体来说,处理器会优先处理更具体的异常类型,如果没有找到匹配的处理器,那么它会寻找处理更一般异常类型的处理器。

到此这篇关于SpringBoot自定义全局异常处理器的文章就介绍到这了,更多相关SpringBoot全局异常处理器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Spring Boot整合JWT的实现步骤

    Spring Boot整合JWT的实现步骤

    本文主要介绍了Spring Boot整合JWT,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • jsp中存取session值简单介绍

    jsp中存取session值简单介绍

    这篇文章主要介绍了jsp中存取session值简单介绍,涉及request和session的域操作等相关内容,具有一定参考价值,需要的朋友可以了解下。
    2017-11-11
  • Java Map的compute方法举例详解

    Java Map的compute方法举例详解

    Java中的Map是一种用于存储键值对的数据结构,它提供了一系列的方法来操作和访问其中的元素,下面这篇文章主要给大家介绍了关于Java Map的compute方法举例详解的相关资料,需要的朋友可以参考下
    2024-06-06
  • SpringBoot整合Caffeine使用示例

    SpringBoot整合Caffeine使用示例

    Spring Boot 和 Caffeine 可以很容易地进行整合,Caffeine 是一个现代化的 Java 缓存库,提供了高性能和灵活的缓存策略,本文给大家介绍了SpringBoot整合Caffeine使用示例,需要的朋友可以参考下
    2024-07-07
  • SpringBoot项目执行脚本 自动拉取最新代码并重启的实例内容

    SpringBoot项目执行脚本 自动拉取最新代码并重启的实例内容

    在本篇文章里小编给大家整理的是一篇关于SpringBoot项目执行脚本 自动拉取最新代码并重启的实例内容,有需要的朋友们参考下。
    2019-12-12
  • spring boot 静态资源处理方法

    spring boot 静态资源处理方法

    本篇文章主要介绍了spring boot 静态资源处理方法。小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • 详解Java中的实例初始化块(IIB)

    详解Java中的实例初始化块(IIB)

    在本篇文章里我们针对Java中的实例初始化块(IIB)做想详细分析,有需要的朋友们可以跟着学习参考下。
    2018-10-10
  • JAVA实现往字符串中某位置加入一个字符串

    JAVA实现往字符串中某位置加入一个字符串

    这篇文章主要介绍了JAVA实现往字符串中某位置加入一个字符串,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-08-08
  • 阿里云主机上安装jdk 某库出现问题的解决方法

    阿里云主机上安装jdk 某库出现问题的解决方法

    今天安装jdk到阿里云服务上,首先看下阿里云是32位还是64位的,如果是32位下载32位的包,如果是64位的下载64位的包,下面与大家分享下安装过程中遇到问题的解决方法
    2013-06-06
  • Java基于Calendar类输出指定年份和月份的日历代码实例

    Java基于Calendar类输出指定年份和月份的日历代码实例

    这篇文章主要介绍了Java 使用Calendar类输出指定年份和月份的日历,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02

最新评论