Spring Boot 全局异常处理

Spring boot全局异常处理

开发过程中难免会遇到异常处理,把异常信息进行封装,返回给用户能够理解的信息。但是异常这么多,我们不可能每个异常都能够完美处理,所以我们需要一个能够捕获到全局的异常,然后处理,以特定的格式返回给前端。spring boot就提供了@ControllerAdvice注解对异常进行全局捕获。

1、统一前端返回数据(JSON)

所有返回给前端的信息,都封装在ResponseData里面

public class ResponseData<T> implements Serializable {

    private static final long serialVersionUID = -3482839797434946211L;
    private int code;
    private String msg;
    private T data;

    ResponseData() {
    }

    ResponseData(int code, String msg, T data) {
        this.code = code;
        this.msg = msg;
        this.data = data;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}
2、定义常见的错误msg和code

这些错误信息都是不变的可以定义成一个枚举类型,里面包含code和msg

public enum ErrorCodeEnum {
    /**
     * 服务端错误
     */
    SERVER_ERROR(1000, "服务端错误"),
    /**
     * 参数错误
     */
    SERVER_ERROR_PARAM(2000, "参数错误"),
    /**
     * 业务异常
     */
    BUSINESS_ERROR(3000, "业务异常"),

    /**
     * 网络异常
     */
    NETWORK_ERROR(4000, "网络异常");

    private String msg;
    private int code;

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

    public String getMsg() {
        return msg;
    }

    public int getCode() {
        return code;
    }
}
3、定义业务异常相关

业务异常有很多,这里我使用统一的业务异常BusinessException其他的业务异常可以继承统一业务异常

public class BusinessException extends RuntimeException {

    private static final long serialVersionUID = 2066878262694332718L;
    private ErrorCodeEnum errorCode;
    private String msg;

    public BusinessException(ErrorCodeEnum code, Throwable cause) {
        super(code.getMsg(), cause);
        this.errorCode = code;
    }

    public BusinessException(ErrorCodeEnum code, String cause) {
        super(cause);
        this.errorCode = code;
        this.msg = cause;
    }

    public BusinessException(ErrorCodeEnum code) {
        this.errorCode = code;
        this.msg = code.getMsg();
    }

    public ErrorCodeEnum getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(ErrorCodeEnum errorCode) {
        this.errorCode = errorCode;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }
}
4、定义全局异常捕获
@ControllerAdvice
@Slf4j
public class DefaultExceptionHandler {

    @ExceptionHandler(value = IllegalArgumentException.class)
    @ResponseBody
    public ResponseData handlerError(HttpServletRequest req, IllegalArgumentException ex) {
        log.warn("非法参数,path:{},param:{}", req.getRequestURI(), req.getQueryString(), ex);
        return handleErrorInfo(ErrorCodeEnum.SERVER_ERROR_PARAM.getMsg(), ErrorCodeEnum.SERVER_ERROR_PARAM.getCode());
    }

    @ExceptionHandler(value = BusinessException.class)
    @ResponseBody
    public ResponseData handlerError(HttpServletRequest req, BusinessException ex) {
        log.warn("BusinessException,path:{},param:{}", req.getRequestURI(), req.getQueryString(), ex);
        return handleErrorInfo(ex.getMsg(), ex.getErrorCode().getCode());
    }

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public ResponseData handlerError(HttpServletRequest req, Exception ex) {
        log.warn("exception! path:{},param:{}", req.getRequestURI(), req.getQueryString(), ex);
        return handleErrorInfo(ErrorCodeEnum.SERVER_ERROR.getMsg(), ErrorCodeEnum.SERVER_ERROR.getCode());
    }

    private ResponseData<String> handleErrorInfo(String msg, int code) {
        ResponseData<String> responseData = new ResponseData<>();
        responseData.setCode(code);
        responseData.setMsg(msg);
        responseData.setData(msg);
        return responseData;
    }
}
5、测试Controller
@RestController
public class TestController {

    @GetMapping("/test")
    public ResponseData test(String exceptionInfo){
        if ("参数错误".equals(exceptionInfo)) {
            throw new IllegalArgumentException();
        }
        if ("业务异常".equals(exceptionInfo)){
            throw new BusinessException(ErrorCodeEnum.BUSINESS_ERROR);
        }
        if ("其他异常".equals(exceptionInfo)){
            throw new RuntimeException();
        }

        ResponseData<String> responseData = new ResponseData<>();
        responseData.setData("没有异常");
        responseData.setCode(0);
        responseData.setMsg("没有异常");
        return responseData;
    }
}
6、postman测试

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值