目录
1.通用返回对象
不管成功还是失败,期望给前端返回类型相同的对象,并给对象补充一些信息,告诉前端这个请求在业务层面上是成功还是失败
例如:
1.1 创建一个BaseResponse类
不确定属性data的类型,所以使用泛型
package com.ttsin.usercenter.common;
import lombok.Data;
import java.io.Serializable;
/**
* 通用返回类
* @param <T>
* @author ttsin
*/
@Data
public class BaseResponse<T> implements Serializable {
/**
* 状态码
*/
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());
}
}
1.2 通用返回类的工具类ResultUtil
成功,调用success(),只需要传入data参数
失败,调用error(),根据事先创建的 枚举--自定义的错误码对象
package com.ttsin.usercenter.common;
/**
* 通用返回类的工具类
* @author ttsin
*/
public class ResultUtil {
/**
* 成功
* @param data
* @param <T>
* @return
*/
public static <T> BaseResponse<T> success(T data){
return new BaseResponse<>(0,data,"ok");
}
/**
* 失败
* @param errorCode
* @return
*/
public static BaseResponse error(ErrorCode errorCode){
return new BaseResponse(errorCode);
}
public static BaseResponse error(int code,String message,String description){
return new BaseResponse(code,null,message,description);
}
public static BaseResponse error(ErrorCode errorCode,String message,String description){
return new BaseResponse(errorCode.getCode(),null,message,description);
}
public static BaseResponse error(ErrorCode errorCode,String description){
return new BaseResponse(errorCode.getCode(),null,errorCode.getMessage(),description);
}
}
1.3 自定义错误码枚举类 ErrorCode
因为前端的HTTP状态码默认的值比较少,所以需要自己定义状态码,成功的状态码是0,失败的原因过多,所以使用枚举定义几个不同的状态码(根据自己的业务)
package com.ttsin.usercenter.common;
/**
* @author ttsin
*/
public enum ErrorCode {
SUCCESS(0,"ok",""),
PARAMS_ERROR(40000,"请求参数错误",""),
NULL_ERROR(40001,"请求数据为空",""),
NOT_LOGIN(40100,"未登录",""),
NO_AUTH(40101,"无权限",""),
SYSTEM_ERROR(50000,"系统内部异常","");
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;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
public String getDescription() {
return description;
}
}
2.封装全局异常处理
如下图,当每个注册失败的逻辑直接返回,代码不优雅,这里希望抛出一个自定义的异常,再使用全局异常处理器根据异常信息创建BaseResponse对象
2.1 定义业务异常类
自定义异常的优点:
ⅰ相对于 java 的异常类,支持更多字段(如code,description)
ⅱ自定义构造函数,更灵活 / 快捷的设置字段
package com.ttsin.usercenter.exception;
import com.ttsin.usercenter.common.ErrorCode;
/**
* 自定义异常类
* @author ttsin
*/
public class BusinessException extends RuntimeException{
private final int code;
private final String description;
public BusinessException(String message, int code, 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;
}
}
2.2 编写全局异常处理器
作用:
ⅰ捕获代码中所有的异常,内部消化,让前端得到更详细的业务报错 / 信息
ⅱ同时屏蔽掉项目框架本身的异常(不暴露服务器内部状态)
ⅲ集中处理,比如记录日志
实现:
ⅰSpring AOP:在调用方法前后进行额外的处理
package com.ttsin.usercenter.exception;
import com.ttsin.usercenter.common.BaseResponse;
import com.ttsin.usercenter.common.ErrorCode;
import com.ttsin.usercenter.common.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @author ttsin
*/
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(BusinessException.class)
public BaseResponse businessExceptionHandler(BusinessException e){
log.error("businessException:"+e.getMessage(),e);
return ResultUtil.error(e.getCode(),e.getMessage(),e.getDescription());
}
@ExceptionHandler(RuntimeException.class)
public BaseResponse runtimeExceptionHandler(BusinessException e){
log.error("runtimeException",e);
return ResultUtil.error(ErrorCode.SYSTEM_ERROR,e.getMessage(),"");
}
}