SpringBoot 全局异常处理

本文详细介绍了如何在SpringBoot应用中实现全局异常处理,包括创建统一异常接口、异常枚举类、自定义异常、统一响应结果以及全局异常处理类。通过这种方式,可以将各种异常转换为统一的错误信息,方便前后端交互并简化错误处理流程。
摘要由CSDN通过智能技术生成

SpringBoot 全局异常处理

为什么要统一异常处理

在日常的开发过程中,有许多的异常需要我们处理,所有异常的父类都是Throwable类。其中Exception异常是可以进行手动处理的,在程序运行过程中,也会出现各种业务异常,需要自定义,可能返回500,404,等等,前端拿到这些异常可能不方便处理,如果可以统一一个全局异常,是什么错误就返回什么信息和code码给前端,前端更便于处理。

开始

1. 创建一个异常使用的统一接口

package com.rich.common.exception;

/**
 * <p>
 * 全局统一异常处理-自定义异常处理接口
 * </p>
 *
 * @author: jinxs
 * @since: 2022/9/1 8:53
 */
public interface BaseErrorInfoInterface {


    /**
     * 获取状态码
     * @return
     */
    String getCode();


    /**
     * 获取异常信息
     * @return
     */
    String getMsg();
}

2. 创建异常错误枚举类

package com.rich.common.enums;

import com.rich.common.exception.BaseErrorInfoInterface;

/**
 * <p>
 * 全局异常错误枚举类
 * </p>
 *
 * @author: jinxs
 * @since: 2022/9/1 9:03
 */
public enum BaseErrorEnum implements BaseErrorInfoInterface {

    SUCCESS("200","成功"),
    BODY_NOT_MATCH("400","数据格式不匹配"),
    NOT_FOUND("404","资源未找到"),
    INTERNAL_SERVER_ERROR("500","服务器内部错误!"),
    SERVER_BUSY("503","服务器繁忙"),
    REQUEST_METHOD_SUPPORT_ERROR("10001","当前请求方法不支持"),
    REQUEST_DATA_NULL("10002","当前请求参数为空"),
    USER_NOT_EXISTS("10003","用户不存在"),
    USER_INVALID("10004","登录信息已失效,请重新登录"),
    PASSWORD_ERROR("10005","密码错误"),
    USER_NAME_LOCK("10006","账号被锁定");


    private String code;

    private String msg;


    BaseErrorEnum(String code, String msg) {
        this.code = code;
        this.msg = msg;
    }

    @Override
    public String getCode() {
        return this.code;
    }

    @Override
    public String getMsg() {
        return this.msg;
    }

}

3.创建语出异常处理类

package com.rich.common.exception;

import com.rich.common.enums.BaseErrorEnum;
import lombok.Data;

/**
 * <p>
 * 全局统一异常基础异常
 * </p>
 *
 * @author: jinxs
 * @since: 2022/9/1 9:53
 */
@Data
public class BaseException extends RuntimeException{


    /***
     * 错误码
     */
    private String code;


    /**
     * 错误消息
     */
    private String msg;


    /**
     * 默认构造
     */
    public BaseException() {
        super();
    }

    /**
     * 自定义构造
     * @param baseErrorEnum
     */
    public BaseException(BaseErrorEnum baseErrorEnum){
        super(baseErrorEnum.getCode());
        this.code = baseErrorEnum.getCode();
        this.msg = baseErrorEnum.getMsg();
    }

}

说明: 这里的 BaseException 需要继承RuntimeException 而不是Exception原因是RuntimeException是在运行时抛出的在编译的时候不需要做任何处理,而Exception在编译期间就要做响应的处理。如果你throw了一个RuntimeException,不需要做额外操作;而throw一个Exception,程序会要求你try-catch,否则你根本启动不了程序

4. 设计统一结果响应

package com.rich.common.pojo.base;

import lombok.AllArgsConstructor;
import lombok.Data;

/**
 * <p>
 * 基础相应类
 * </p>
 *
 * @author: jinxs
 * @since: 2022/9/1 10:09
 */
@Data
@AllArgsConstructor
public class BaseResponse<T> {

    private String code;

    private String msg;

    private T data;

}

package com.rich.common.pojo.base;

import com.rich.common.enums.BaseErrorEnum;

/**
 * <p>
 * 统一返回
 * </p>
 *
 * @author: jinxs
 * @since: 2022/9/1 10:16
 */
public class RespGenerator {

    /**
     * 正常返回时调用方法
     * @param data
     * @return
     */
    public static BaseResponse success(Object data){
        return new BaseResponse(BaseErrorEnum.SUCCESS.getCode(),"接口调用成功!",data);
    }


    /**
     * 失败时调用方法(入参是异常枚举)
     * @param baseErrorEnum
     * @return
     */
    public static BaseResponse<Object>fail(BaseErrorEnum baseErrorEnum){
        return new BaseResponse<Object>(baseErrorEnum.getCode(),baseErrorEnum.getMsg(),null);
    }


    /**
     * 调用失败(提供给GLobalExceptionHandler类使用)
     * @param code
     * @param message
     * @return
     */
    public static BaseResponse<Object>fail(String code,String message) {
        return new BaseResponse<Object>(code, message, null);
    }
}

5. 添加全局异常处理类

package com.rich.common.exception;

import com.rich.common.enums.BaseErrorEnum;
import com.rich.common.pojo.base.BaseResponse;
import com.rich.common.pojo.base.RespGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

/**
 * <p>
 * 全局异常处理
 * </p>
 *
 * @author: jinxs
 * @since: 2022/9/1 10:02
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {

    /**
     * 处理自定义异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = BaseException.class)
    public BaseResponse<Object> baseExceptionHandler(BaseException e) {
        log.error("发生业务异常!{}", e.getMsg());
        return RespGenerator.fail(e.getCode(), e.getMsg());
    }

    /**
     * 处理空指针异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = NullPointerException.class)
    public BaseResponse<Object> exceptionHandler(NullPointerException e) {
        log.error("发生空指针异常!{}",e.getMessage());
        return RespGenerator.fail(BaseErrorEnum.BODY_NOT_MATCH);
    }

    /**
     * 处理其他异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public BaseResponse<Object> exceptionHandler(Exception e) {
        log.error("未知异常!{}",e.getMessage());
        return RespGenerator.fail(BaseErrorEnum.INTERNAL_SERVER_ERROR);
    }
}

说明:

  • @RestControllerAdvice注解是@ResponseBody和@ControllerAdvice的组合。
  • @ResponseBody注解:通常用来将java对象转成JSON对象,返回给前端JSON数据
  • @ControllerAdvice注解:结合方法型注解@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常,从而达到不同类型的异常区别处理的目的。
  • @ExceptionHandler注解统一处理某一类异常,从而能够减少代码重复率和复杂度,value值为什么异常类型,就处理什么异常类型的逻辑。

6.测试

在这里插入图片描述
结果:
在这里插入图片描述

完结!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值