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全局异常处理器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解Java冒泡排序

    详解Java冒泡排序

    本篇文章通过代码实例给大家详细分析了Java冒泡排序的原理,有兴趣的朋友可以学习下。
    2018-02-02
  • 使用Arthas定位问题及分析

    使用Arthas定位问题及分析

    本文通过使用Arthas工具对一个bug进行分析,发现该bug的原因是不同类型的动态代理(JDK和CGlib)实现机制的不同导致的
    2025-01-01
  • java中如何判断JSONObject是否存在某个Key

    java中如何判断JSONObject是否存在某个Key

    这篇文章主要介绍了java中如何判断JSONObject是否存在某个Key,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-07-07
  • 使用shardingsphere对SQLServer坑的解决

    使用shardingsphere对SQLServer坑的解决

    本文主要介绍了使用shardingsphere对SQLServer坑的解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-03-03
  • java内部类使用总结

    java内部类使用总结

    本文主要介绍了java内部类使用总结。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-02-02
  • Spring Boot自定义配置实现IDE自动提示功能

    Spring Boot自定义配置实现IDE自动提示功能

    这篇文章主要介绍了Spring Boot自定义配置实现IDE自动提示功能,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-08-08
  • JAVA 日常开发中Websocket示例详解

    JAVA 日常开发中Websocket示例详解

    JAVA |日常开发中Websocket详解,WebSocket是一种在单个TCP连接上进行全双工通信的协议,它在Web应用中实现了客户端与服务器之间的实时数据传输,本文将详细介绍Java开发中WebSocket的使用,包括基本概念、Java API、使用示例以及注意事项,感兴趣的朋友一起看看吧
    2024-12-12
  • Java Synchronized的偏向锁详细分析

    Java Synchronized的偏向锁详细分析

    synchronized作为Java程序员最常用同步工具,很多人却对它的用法和实现原理一知半解,以至于还有不少人认为synchronized是重量级锁,性能较差,尽量少用。但不可否认的是synchronized依然是并发首选工具,本文就来详细讲讲
    2023-04-04
  • Java构造方法 super 及自定义异常throw合集详解用法

    Java构造方法 super 及自定义异常throw合集详解用法

    异常是程序中的一些错误,但不是所有错误都是异常,且错误有时候是可以避免的,super可以理解为是指向自己超(父)类对象的一个指针,而这个超类指的是离自己最近的一个父类,构造器也叫构造方法、构造函数,是一种特殊类型的方法,负责类中成员变量(域)的初始化
    2021-10-10
  • 基于spring注入为null的原因及解决方案

    基于spring注入为null的原因及解决方案

    这篇文章主要介绍了spring注入为null的原因及解决方案,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-08-08

最新评论