前后端分离(springboot+vue)的业务异常处理

将业务异常处理为相应响应状态(meta.code),前端拦截后做出处理

一、后端异常处理

1、自定义异常类

继承自RuntimeException

public class ItokenException extends RuntimeException {


    private ItokenException(ExceptionData exceptionData) {
        super(exceptionData.getErrorMessage());
    }

    /**
     * 功能描述 异常枚举类抛出
     *
     * @return com.funtl.itoken.commons.exception.ItokenException
     * @author qyh
     * @date 2020/3/11
     */
    public static ItokenException buildException(ErrorCodeEnum errorCodeEnum) {
        ExceptionData exceptionData = new ExceptionData(errorCodeEnum.getCode(), errorCodeEnum.getMsg());
        return new ItokenException(exceptionData);
    }

    /**
     * 功能描述 异常枚举类加自定义信息
     *
     * @return com.funtl.itoken.commons.exception.ItokenException
     * @author qyh
     * @date 2020/3/11
     */
    public static ItokenException buildException(ErrorCodeEnum errorCodeEnum, String msg) {

        ExceptionData data = null;
        if (StringUtils.isEmpty(msg)) {
            data = new ExceptionData(errorCodeEnum.getCode(), errorCodeEnum.getMsg());
        } else {
            data = new ExceptionData(errorCodeEnum.getCode(), errorCodeEnum.getMsg() + msg);
        }

        return new ItokenException(data);
    }
}

2、自定义异常类型枚举

public enum ErrorCodeEnum {

    // 基础错误异常
    ERROR(-1, "错误异常"),
    SYSTEM_ERROR(0, "系统错误"),
    INVALID_PARAMS(1, "非法参数"),
    PROC_FAILED(2, "处理失败"),
    DATA_NOT_FOUND(3, "数据不存在"),
    DATA_EMPTY(4, "数据为空"),
    ;

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

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

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

3、自定义接口返回信息

包含meta(请求状态及信息)、data(响应数据)

public class ResponseResult<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 响应状态
     */
    private ResponseCodeMessage meta;

    /**
     * 响应数据
     */
    private T data;


    /**
     * 功能描述 响应构造器
     *
     * @param code 响应码
     * @param msg  响应消息
     * @param data 响应数据
     * @return
     * @author qyh
     * @date 2020/3/29
     */
    public ResponseResult(Integer code, String msg, T data) {
        this.meta = new ResponseCodeMessage(code, msg);
        this.data = data;
    }

    /**
     * 功能描述 失败的响应
     *
     * @param
     * @return com.funtl.itoken.commons.response.ResponseResult<T>
     * @author qyh
     * @date 2020/3/29
     */
    public static <T> ResponseResult<T> fail() {
        return new ResponseResult<>(ResponseCodeMessageEnum.UNKNOWN_ERROR.getCode(),
                ResponseCodeMessageEnum.UNKNOWN_ERROR.getMsg(), (T) null);
    }

    /**
     * 功能描述 自定义状态
     *
     * @param
     * @return com.funtl.itoken.commons.response.ResponseResult<T>
     * @author qyh
     * @date 2020/3/29
     */
    public static <T> ResponseResult<T> custom(Integer code, String msg, T data) {
        return new ResponseResult<>(code, msg, data);
    }

    /**
     * 功能描述 成功的响应
     *
     * @param
     * @return com.funtl.itoken.commons.response.ResponseResult<T>
     * @author qyh
     * @date 2020/3/29
     */
    public static <T> ResponseResult<T> success(T data) {
        return new ResponseResult<>(ResponseCodeMessageEnum.SUCCESS.getCode(),
                ResponseCodeMessageEnum.SUCCESS.getMsg(), data);
    }

    @Override
    public String toString() {
        return "ResponseResult{" +
                "responseCodeMessage=" + meta +
                ", data=" + data +
                '}';
    }
}

4、全局异常处理

@ControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @ResponseBody
    @ExceptionHandler(value = Throwable.class)
    public ResponseResult<String> exceptionHandler(HttpServletRequest request, HttpServletResponse response, Exception e) {
        if (e instanceof ItokenUaaException) {
            // 业务异常信息组装
            ItokenUaaException be = (ItokenUaaException) e;
            LOGGER.error("request:{} ,message:{}", request.toString(), be.getMessage());
            return new ResponseResult<>(be.getCode(), be.getMessage(), null);
        } else {
            LOGGER.error("request:{} ,message:{}", request.toString(), e);
            return ResponseResult.failEnum(ResponseCodeMessageEnum.UNKNOWN_ERROR);
        }
    }
}

二、前端异常处理(axios拦截器)

与后端定义好接口响应状态、如10010为用户未登录,拦截到10010后可重定向至登陆页面

// 添加响应拦截器
service.interceptors.response.use(function (response) {
    // 对响应数据做点什么
    let data = response.data;
    if (data.meta.code !== 200) {
        if (data.meta.code === 10010) {
            ElementUI.Message.error("用户没有登陆");
            Router.push({name: "login"});
        } else {
            ElementUI.Message.error(data.meta.msg);
            return Promise.reject(data);
        }
    } else {
        return response;
    }
}, function (error) {
    return Promise.reject(error);
});

Logo

前往低代码交流专区

更多推荐