通用返回对象

定义BaseResponse

  • 这里面主要定义一些返回给前端的数据
  • code:响应码
  • data:数据
  • message:状态码信息
  • description:状态码描述(详情)
  • 根据传入参数或者说需求,定义一些构造方法进行重载
  • 代码:
@Data
public class BaseResponse<T> {
    private int code;
    private T data;
    private String message;
    private String description;

    public BaseResponse(int code, T data, String message,String description) {
        this.code = code;
        this.data = data;
        this.message = message;
        this.description = description;
    }
    public BaseResponse(int code, T data, String message) {
        this(code,data,message,"");
    }
    public BaseResponse(int code, T data) {
        this(code,data,"","");
    }
    public BaseResponse(ErrorCode errorCode) {
        this(errorCode.getCode(),null,errorCode.getMessage(),errorCode.getDescription());
    }
}

定义ResultUtils

作用:对BaseResponse进行一层封装,可以直接用工具类来返回,让工具类去帮我们创建BeseResponse类的实例对象

  • 里面定义了两类方法
  • 成功
public static <T>BaseResponse<T> success(T data) {
    return new BaseResponse<>(0,data,"ok");
}
  • 失败
    看下面的全局异常处理

封装全局异常处理

定义业务错误状态码

  • 创建一个枚举类,里面定义我们业务出错的信息
  • 其中包括 code、message、description,因为我们不需要修改这些属性,将其定义为final
/**
* 状态码
*/
 private final int code;
/**
* 状态码信息
*/
 private final String message;
/**
* 状态码描述(详情)
*/
 private final String description;
  • 定义一个构造器
ErrorCode(int code, String message, String description) {
    this.code = code;
    this.message = message;
    this.description = description;
}
  • 定义一些业务中需要的一些异常信息
SUCCESS(0,"ok",""),
PARAMS_ERROR(40000,"请求参数错误",""),
NULL_ERROR(40001,"请求参数为空",""),
NOT_LOGIN(40100,"未登录",""),
NO_AUTH(40101,"无权限",""),
SYSTEM_ERROR(50000,"系统异常","");
  • 提供getter方法
  • 在我们的ResultUtils中定义失败的方法,根据业务需求或参数不同进行重载
/**
     * 失败
     * @param errorCode
     * @return
     * @param <T>
     */
    public static <T>BaseResponse<T> error(ErrorCode errorCode) {
        return new BaseResponse<>(errorCode);
    }

    public static <T>BaseResponse<T> error(ErrorCode errorCode,String description) {
        return new BaseResponse<>(errorCode.getCode(),null,errorCode.getMessage(),description);
    }

    public static <T>BaseResponse<T> error(ErrorCode errorCode,String message, String description) {
        return new BaseResponse<>(errorCode.getCode(),null,message,description);
    }

    public static <T>BaseResponse<T> error(int code,String message, String description) {
        return new BaseResponse<>(code,null,message,description);
    }

定义业务异常类

作用:

  1. 相对于Java的异常类,支持更多字段
  2. 自定义构造函数,更灵活 / 快捷的设置字段
public class BusinessException extends RuntimeException{
    private final int code;
    private final String description;

    public BusinessException(int code, String message, String description) {
        super(message);
        this.code = code;
        this.description = description;
    }

    public BusinessException(ErrorCode errorCode) {
        super(errorCode.getMessage());
        this.code = errorCode.getCode();
        this.description = errorCode.getDescription();
    }
    public BusinessException(ErrorCode errorCode,String description) {
        super(errorCode.getMessage());
        this.code = errorCode.getCode();
        this.description = description;
    }

    public int getCode() {
        return code;
    }

    public String getDescription() {
        return description;
    }
}
  • 好处:既可以在controller层调用,也可以在业务层使用

封装全局处理器

作用:

  1. 捕获代码中所有的异常,内部消化,让前端得到更详细的业务报错 / 信息
  2. 同时屏蔽掉项目框架本身的异常(不暴露服务器内部状态)
  3. 集中处理,比如记录日志

实现:

使用Spring AOP思想,在调用方法前后进行额外的处理

@RestControllerAdvice注解

@RestControllerAdvice的作用范围是:单个项目中所有使用了@RequestMapping(像@PostMapping底层是使用了@RequestMapping注解的也支持)的类都归他管,那归@RestControllerAdvice他管了,已经清楚了,@RestControllerAdvice这个注解要干什么呢?好像根据他的名字我们只能看到这是一个应用于Controller层的切面注解,其他就看不到了。其实该注解还需要与其他注解配合使用才有意义,单独的使用该注解是没有任何意义的,下面就来介绍下该注解都可以与哪些注解配合使用

@ExceptionHandler注解

@RestControllerAdvice+@ExceptionHandler这两个注解的组合,被用作项目的全局异常处理,一旦项目中发生了异常,就会进入使用了@RestControllerAdvice注解类中使用了@ExceptionHandler注解的方法,我们可以在这里处理全局异常,将异常信息输出到指定的位置。并对所有的错误信息进行归置,下面是示例代码:

@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
    /**
     * 自定义异常
     * @param e
     * @return
     */
    @ExceptionHandler(BusinessException.class)
    public BaseResponse businessException(BusinessException e) {
        log.info("businessException" + e.getMessage(),e);
        return ResultUtils.error(e.getCode(),e.getMessage(),e.getDescription());
    }
    /**
     * 系统内异常
     * @param e
     * @return
     */
    @ExceptionHandler(RuntimeException.class)
    public BaseResponse businessException(RuntimeException e) {
        log.info("runtimeException",e);
        return ResultUtils.error(ErrorCode.SYSTEM_ERROR,e.getMessage(),"");
    }
}

全局异常处理器的好处

  1. 前端不需要知道我们在哪里报错了
  2. 当我们后端报错之后,不会将系统本身的报错信息返回给前端(哪个类的哪个方法哪里出错)
  3. 提高了安全性