项目学习总结
后端统一公共数据返回类
一般后端响应返回类会有3个字段,code:响应码,可以自己定义,也可以直接使用已有的http状态码;msg:提示内容,通常也是自己定义,然后返回给后端;data:后端返回的数据,前端拿到这个数据后会数据在页面上展示出来。一般情况下都是使用json返回数据,由于无法确定返回的数据具体是什么对象,所以这里需要使用泛型。
公共数据返回类
/**
* 统一数据返回
*/
@Data
public class ApiRestResponse<T> {
/**
* 响应码
*/
private Integer code;
/**
* 提示信息
*/
private String msg;
/**
* 返回的数据
*/
private T data;
public ApiRestResponse(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public ApiRestResponse() {
this(Constant.OK_CODE, Constant.OK_MSG);
}
/**
* 请求成功,设置数据返回给前端
* @param result
* @param <T>
* @return
*/
public static <T> ApiRestResponse<T> success(T result) {
ApiRestResponse<T> response = new ApiRestResponse<>();
response.setData(result);
return response;
}
/**
* 请求成功,使用默认的code和msg返回到前端,适用于不需要给前端返回数据的情形
* @param <T>
* @return
*/
public static <T> ApiRestResponse<T> success() {
return new ApiRestResponse<>();
}
/**
* 请求使用,返回自定义的code和msg
* @param code
* @param msg
* @param <T>
* @return
*/
public static <T> ApiRestResponse<T> error(Integer code, String msg) {
return new ApiRestResponse<>(code, msg);
}
/**
* 请求失败,出现异常,返回异常的code和msg
* @param ex 抛出的异常,
* @param <T>
* @return
*/
public static <T> ApiRestResponse<T> error(IMallExceptionEnum ex) {
return new ApiRestResponse<>(ex.getCode(), ex.getMsg());
}
}
统一异常处理
统一异常处理有两个点,第一需要自定义异常,第二需要全局捕获异常。这里面会使用到@ControllerAdvice注解。
自定义异常类
这里面继承的是RuntimeException,这样后面在抛出这个异常时不需要使用try catch去处理异常。
public class MallException extends RuntimeException{
private String msg;
private Integer code;
public MallException(IMallExceptionEnum mallExceptionEnum) {
this.code = mallExceptionEnum.getCode();
this.msg = mallExceptionEnum.getMsg();
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
}
全局异常处理
这里需要借助@ControllerAdvice注解。
/**
* 统一处理异常
*
* 1、@ControllerAdvice配合@ExceptionHandler处理全局异常
* 可以指定处理某个包下的所有Controller、也可以是指定处理被某个注解修饰的Controller,不写则默认是所有的Controller
*
*/
@ControllerAdvice
public class GlobalExceptionHandler {
private final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* @ExceptionHandler(Exception.class):表示此方法处理Exception类型的异常,如果参数为空,将默认方法参数列表中列出的任何异常
* @param e
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public Object handleException(Exception e) {
log.error("Default Exception: ", e);
return ApiRestResponse.error(IMallExceptionEnum.SYSTEM_ERROR);
}
/**
* @ExceptionHandler(MallException.class): 表示此方法处理MallException类型的异常
* @param e
* @return
*/
@ExceptionHandler(MallException.class)
@ResponseBody
public Object HandlerIMallException(MallException e) {
log.error("MallException: " + e);
return ApiRestResponse.error(e.getCode(), e.getMsg());
}
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public ApiRestResponse handleMethodArgumentNotValidException(
MethodArgumentNotValidException e) {
log.error("MethodArgumentNotValidException: ", e);
return handleBindingResult(e.getBindingResult());
}
private ApiRestResponse handleBindingResult(BindingResult result) {
//把异常处理为对外暴露的提示
List<String> list = new ArrayList<>();
if (result.hasErrors()) {
List<ObjectError> allErrors = result.getAllErrors();
for (ObjectError objectError : allErrors) {
String message = objectError.getDefaultMessage();
list.add(message);
}
}
if (list.size() == 0) {
return ApiRestResponse.error(IMallExceptionEnum.REQUEST_PARAM_ERROR);
}
return ApiRestResponse
.error(IMallExceptionEnum.REQUEST_PARAM_ERROR.getCode(), list.toString());
}
}