Springboot统一处理返回结果和异常

870 阅读2分钟

Springboot统一处理返回结果和异常

1.首先创建结果实体

  • 创建接口IErrorCode
public interface IErrorCode {
    /**
     * 返回状态码
     * @return 返回状态码
     */
    Integer getStatus();

    /**
     * 返回信息
     * @return 返回信息
     */
    String getMessage();
}
  • 创建枚举类ResultCode

    public enum ResultCode implements IErrorCode{
        /**
         * 操作成功
         */
        SUCCESS(200, "操作成功"),
        /**
         * 操作失败
         */
        FAILED(500, "操作失败"),
        /**
         * 参数检验失败
         */
        VALIDATE_FAILED(404, "参数检验失败"),
        UNAUTHORIZED(401, "暂未登录或token已经过期"),
        FORBIDDEN(403, "没有相关权限");
        private final Integer status;
        private final String message;
    
        private ResultCode(Integer status, String message) {
            this.status = status;
            this.message = message;
        }
    
        @Override
        public Integer getStatus() {
            return status;
        }
    
        @Override
        public String getMessage() {
            return message;
        }
    }
    
  • 创建结果实体类

    @Data
    @JsonPropertyOrder(value = {"status", "message", "data"})
    public class CommonResult<T> {
    
        /**
         * 请求状态
         */
        private Integer status;
    
        /**
         * 提示信息
         */
        private String message;
    
        /**
         * 返回体类型
         */
        private T data;
    
        public CommonResult(){}
    
        public CommonResult(String message){
            this.status = 200;
            this.message = message;
        }
    
        public CommonResult(String message, T data) {
            this.status = 200;
            this.message = message;
            this.data = data;
        }
    
        public CommonResult(Integer status, String message, T data){
            this.status = status;
            this.message = message;
            this.data = data;
        }
    
    
        /**
         * 成功返回结果
         *
         * @param data 获取的数据
         */
        public static <T> CommonResult<T> success(T data) {
            return new CommonResult<T>(ResultCode.SUCCESS.getStatus(), ResultCode.SUCCESS.getMessage(), data);
        }
    
        /**
         * 成功返回结果
         *
         * @param data 获取的数据
         * @param  message 提示信息
         */
        public static <T> CommonResult<T> success(T data, String message) {
            return new CommonResult<T>(ResultCode.SUCCESS.getStatus(), message, data);
        }
    
        /**
         * 失败返回结果
         * @param errorCode 错误码
         */
        public static <T> CommonResult<T> failed(IErrorCode errorCode) {
            return new CommonResult<T>(errorCode.getStatus(), errorCode.getMessage(), null);
        }
    
        /**
         * 失败返回结果
         * @param message 提示信息
         */
        public static <T> CommonResult<T> failed(String message) {
            return new CommonResult<T>(ResultCode.FAILED.getStatus(), message, null);
        }
    
        /**
         * 失败返回结果
         */
        public static <T> CommonResult<T> failed() {
            return failed(ResultCode.FAILED);
        }
    
        /**
         * 参数验证失败返回结果
         */
        public static <T> CommonResult<T> validateFailed() {
            return failed(ResultCode.VALIDATE_FAILED);
        }
    
        /**
         * 参数验证失败返回结果
         * @param message 提示信息
         */
        public static <T> CommonResult<T> validateFailed(String message) {
            return new CommonResult<T>(ResultCode.VALIDATE_FAILED.getStatus(), message, null);
        }
    
        /**
         * 未登录返回结果
         */
        public static <T> CommonResult<T> unauthorized(T data) {
            return new CommonResult<T>(ResultCode.UNAUTHORIZED.getStatus(), ResultCode.UNAUTHORIZED.getMessage(), data);
        }
    
        /**
         * 未授权返回结果
         */
        public static <T> CommonResult<T> forbidden(T data) {
            return new CommonResult<T>(ResultCode.FORBIDDEN.getStatus(), ResultCode.FORBIDDEN.getMessage(), data);
        }
    
    }
    

2.创建自定义注解

@Retention(RUNTIME)
@Target({TYPE, METHOD})
@Documented
public @interface ResponseResult {

}

3.创建类ResponseResultHandler处理异常和返回

@RestControllerAdvice
public class ResponseResultHandler implements ResponseBodyAdvice<Object> {


    @Override

    public boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> converterType) {
        /*
          判断类或方法上是否有注解@ResponseResult
          如果类或方法上有注解,则返回真,若没有,则返回假
         */
        return methodParameter.getMethodAnnotation(ResponseResult.class) != null
                || converterType.getAnnotation(ResponseResult.class) != null;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter methodParameter, MediaType mediaType, Class aClass,
                                  ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {
        /*
          将类或方法上带有注解@ResponseResult的,使用统一返回结果实体
         */
        return CommonResult.success(body);
    }

    /**
     * 自定义统一异常处理
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public CommonResult<Object> methodNotAregumentHandler(MethodArgumentNotValidException e){
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        Set<String> errorMessage = new HashSet<>();
        for (FieldError fieldError : fieldErrors){
            errorMessage.add(fieldError.getDefaultMessage());
        }
        return CommonResult.validateFailed(errorMessage.toString());
    }

    @ExceptionHandler(Exception.class)
    public CommonResult<Object> exceptionHandler(Exception e){
        return CommonResult.failed(ResultCode.FAILED);
    }

}