本篇演示如何在Spring Boot中对常见API形式的接口进行统一的异常处理

异常返回封装ExceptionResponse

我们创建一个异常返回类ExceptionResponse,用于在异常时接收异常信息并返回

@Data
public class ExceptionResponse implements Serializable {
    private static final long serialVersionUID = 1L;
    private String error;


    public static ExceptionResponse error(String error) {
        return new ExceptionResponse(error);
    }

    public ExceptionResponse() {

    }

    public ExceptionResponse(String error) {
        this.error = error;
    }
}

异常类

这里创建三个异常类,基础异常类BaseException,两个业务异常类BusinessException和AuthException,两个业务异常类都继承自BaseException,具体要创建多少需要根据实际情况创建,新创建的异常类也继承BaseException即可

基础异常类BaseException

package com.mantis.handler.exception;

import com.mantis.handler.constant.StatusEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * @Description:
 * @author: wei.wang
 * @since: 2020/4/4 16:15
 * @history: 1.2020/4/4 created by wei.wang
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class BaseException extends RuntimeException {

    private Integer code;
    private String message;

    public BaseException(StatusEnum status) {
        super(status.getMessage());
        this.code = status.getCode();
        this.message = status.getMessage();
    }

    public BaseException(Integer code, String message) {
        super(message);
        this.code = code;
        this.message = message;
    }
}

权限异常类AuthException

@Getter
public class AuthException extends BaseException {

    public AuthException() {
        super(StatusEnum.UNAUTHORIZED);
    }

    public AuthException(StatusEnum status) {
        super(status);
    }

    public AuthException(Integer code, String message) {
        super(code, message);
    }
}

业务异常BusinessException

@Getter
public class BusinessException extends BaseException {

    public BusinessException() {
        super(StatusEnum.BUSINESS_EXCEPTION);
    }

    public BusinessException(StatusEnum status) {
        super(status);
    }

    public BusinessException(Integer code, String message) {
        super(code, message);
    }
}

拦截器ProjectExceptionHandler

使用拦截器拦截抛出的异常,并在这里设置返回的状态码

@Slf4j
@RestControllerAdvice
public class ProjectExceptionHandler {

    /**
     * 拦截一般业务异常,直接返回
     * @param response
     * @param ex
     * @return
     */
    @ExceptionHandler({BaseException.class})
    @ResponseBody
    public ExceptionResponse businessExceptionHandler(HttpServletResponse response, BaseException ex) {
        response.setStatus(ex.getCode());
        return ExceptionResponse.error(ex.getMessage());
    }
}

返回状态枚举StatusEnum

使用枚举封装返回状态码和返回内容

@Getter
public enum StatusEnum {
    /**
     * 操作成功
     */
    OK(200, "操作成功"),

    /**
     * 没有权限
     */
    UNAUTHORIZED(401, "没有权限"),
    /**
     * 业务异常
     */
    BUSINESS_EXCEPTION(500, "业务异常"),

    /**
     * 未知异常
     */
    UNKNOWN_ERROR(700, "服务器出错啦");
    /**
     * 状态码
     */
    private Integer code;
    /**
     * 内容
     */
    private String message;

    StatusEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }
}

测试

我们创建一个接口试一下,分别正常返回、抛出AuthException和BusinessException

@Slf4j
@RestController
@RequestMapping(value = "/exception-handler/")
public class ExceptionHandlerController {

    @PostMapping(value = "/test")
    public String exceptionHandler(@RequestBody String str) {
        //throw new AuthException();
        //throw new BusinessException();
        return str;
    }
}

运行结果

正常返回

返回一切正常,状态码200
2020073000003.png

AuthException返回

我们可以看到返回了异常信息和异常状态码401
2020073000001.png

BusinessException返回

我们可以看到返回了异常信息和异常状态码500
2020073000004.png


zero
49 声望6 粉丝

前进