Spring Boot全局异常处理

前言

全局异常处理可以帮助我们拦截接口的报错,返回调用方友好的提示,提高了用户体验的同时,还为我们排查异常提供了便利。
那么如何定义一个全局异常处理呢?它又是怎样帮助我们处理异常,并返回友好提示的呢?咱们肺部哆嗦,直接开搞!

注解说明

本次我们需要用到两个核心注解:
1、@ControllerAdvice:此注解是从Spring3.2版本开始新增的,顾名思义,它是一个控制器增强通知,官方解释说可以与@ExceptionHandler@InitBinder@ModelAttribute注解组合使用
在这里插入图片描述
而默认情况下,此方法应用于所有控制器中,如果想定制化作用于部分控制器,可以使用basePackageClassesbasePackages属性来框定包的范围
在这里插入图片描述
此注解还有一个兄弟@RestControllerAdvice,查看源码可以知道,它是@ControllerAdvice+@ResponseBody的组合注解,新增于Spring4.3版本
在这里插入图片描述
2、@ExceptionHandler:此注解从名字上看也能知道就是一个异常处理器(见名知意了属于是),用于处理指定类的特定异常。我们可以通过设置它的value属性,来指定处理的异常类型

准备工作

所谓的准备工作就是定义一下接口统一返回,和自定义异常。这在项目开发中很常见,这里就简单的贴一下代码内容
首先就是接口统一返回:这在每个人的项目中都会有自己的定义,但都大同小异,这边简单的封装一下
在这里插入图片描述
然后就是自定义异常:这边同样的简单封装一个,项目中可以根据不同的业务,定义不同的异常类型
在这里插入图片描述
在这里插入图片描述
到此,准备工作就已完成,接下来就是主角:全局异常处理类

全局异常处理器

第一步就是创建一个全局异常处理类,并加上@RestControllerAdvice注解,Spring版本低于4.3的可以用@ControllerAdvice+@ResponseBody的组合注解,如果版本低于3.2的朋友,那建议升级一下版本
在这里插入图片描述
接下来就是定义异常处理,要用到@ExceptionHandler注解
这里在注解中指定作用的异常类型为我们准备工作中自定义的异常,然后将异常信息封装成统一接口返回,msg为错误提示:可用于前端展示,detail则为错误描述:可方便接口错误排查定位
在这里插入图片描述
而其他异常类型,我们统一用Exception概括。这里将异常的堆栈信息,拼接成字符串,放在detail中,方便排查异常,而msg则可以根据不同项目的业务来定义友好提示
在这里插入图片描述
到这一步,一个简单的全局异常处理类就算完成。完整代码如下:

package com.jorkeycloud.integration.exception;

import com.jorkeycloud.integration.entity.dto.ResultBody;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.Arrays;

/**
 * @author Jorkey
 * @version v1.0
 **/
@Slf4j
@RestControllerAdvice
public class WebGlobalExceptionHandler {

    public WebGlobalExceptionHandler() {
        log.info("new instance {}", WebGlobalExceptionHandler.class.getName());
    }

    @ExceptionHandler(SysException.class)
    public ResultBody<?>  sysException(SysException e) {
        log.error(e.getMessage(), e);
        Integer code = 500;
        String msg = "系统走神了~";
        String detail = null;
        SysError sysError = e.getError();
        if (sysError != null) {
            if (sysError.getMessage() != null) {
                msg = sysError.getMessage();
            }
            detail = sysError.getDetails();
        }
        return ResultBody.error(code, msg, detail);
    }

    @ExceptionHandler(Exception.class)
    public ResultBody<?> handleException(Exception e) {
        log.error(e.getMessage(), e);
        Integer code = 500;
        String msg = "系统走神了~";
        String detail = null;
        StringBuilder errorString = new StringBuilder(e.toString());
        Arrays.stream(e.getStackTrace()).forEach(item -> {
            errorString.append("。 ").append(item.getFileName()).append(": ").append(item.getMethodName())
                    .append(": ").append(item.getLineNumber());
        });
        if (errorString.length() > 0) {
            detail = errorString.toString();
        }

        return ResultBody.error(code, msg, detail);
    }

}

结果展示

写一个接口来模拟异常
在这里插入图片描述
然后用postman来调用接口,结果分别如下:
第一个异常只有提示,没有描述
在这里插入图片描述
第二个异常有提示,也有描述
在这里插入图片描述
第三个,主动抛出运行时异常
在这里插入图片描述
第四个,空指针异常
在这里插入图片描述
第五个,by zero异常
在这里插入图片描述
最后,成功返回
在这里插入图片描述
以上就是本次全局异常处理的全部内容,有疑问或者有更好方案的话,可以评论区讨论一下共同进步呀。
如果觉得写的不错,不妨点个赞支持一下~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值