引言
后端接口的返回结果类型多样,会使得前端开发成员十分困扰,因此要封装一个结果类,统一返回这个结果类。
对于异常的处理,如果手工捕获异常,需要嵌套大量的try-catch,因此需要自定义异常,配合异常捕获器(aop)来对异常进行统一处理。
实现步骤
1.(异常状态码,异常信息) 封装成一个枚举类 ResponseEnum
package com.example.exceptions.enumeration;
import lombok.Getter;
@Getter
public enum ResponseEnum {
/*
每一个枚举项实际就是这个枚举类的一个对象
*/
SUCCESS(20000, "请求成功"),
UNKNOWN_ERROR(20001,"系统维护中,请稍候重试"),//未被发现的异常不需要告诉用户
TOKEN_EXPIRED(20002, "token过期"),
BY_ZERO_ERROR(20003, "除零异常"),
INVALID_ACCOUNT(20004,"用户名或电话不存在");
private final int code;
private final String message;
//枚举类没有构造方法提供,需要自己写
ResponseEnum(int code, String message) {
this.code = code;
this.message = message;
}
}
2. 自定义异常 (如下示例为自定义的业务异常)
抛出异常一定是请求失败的情况,需要异常状态码,异常信息。
构造方法中需要有ResponseEnum,以便于我们手动抛出异常的时候可以指定它是什么类型的业务异常
( 例:throw new BusinessException(ResponseEnum.INVALID_ACCOUNT); )
package com.example.exceptions;
import com.example.exceptions.enumeration.ResponseEnum;
import lombok.Data;
@Data
//Data注解用于获取ResponseEnum
public class BusinessException extends RuntimeException {
private ResponseEnum response;
public BusinessException(ResponseEnum response) {
this.response = response;
}
}
3. 封装统一结果类 Result
成功情况接收 T data code和msg直接用ResponseEnum.SUCCESS的
失败情况接收 ResponseEnum response (失败情况不需要返回结果)
失败情况接收 String msg 这个是针对未知异常的(程序员尚未发现的异常),统一用ResponseEnum.UNKNOWN_ERROR (用于安抚用户,具体的异常信息我们通过日志打出来,再去解决)
@Data
@Slf4j
//需要提供get、set方法
public class Result<T> {
private int code;
private String msg;
private boolean success;
private T data;
public static <T> Result<T> success(T data) {
Result<T> result = new Result<>();
result.code = ResponseEnum.SUCCESS.getCode();
result.msg = ResponseEnum.SUCCESS.getMessage();
result.success = true;
result.data = data;
return result;
}
public static <T> Result<T> error(ResponseEnum response) {
Result<T> result = new Result<>();
result.code = response.getCode();
result.msg = response.getMessage();
result.success = false;
result.data = null;
return result;
}
//我们尚未发现的异常
public static <T> Result<T> error(String msg) {
Result<T> result = new Result<>();
result.code = ResponseEnum.UNKNOWN_ERROR.getCode();
log.info("出现了一个未知异常:{}", msg);//未知异常自己知道就行了,返回给前端的信息用于安抚用户
result.msg = ResponseEnum.UNKNOWN_ERROR.getMessage();
result.success = false;
return result;
}
}
4. 定义异常捕获器
@RestControllerAdvice (专门用于异常处理的一个aop)
**********************
用@ExceptionHandler (异常的字节码文件)注解
对不同类型的异常进行拦截,并响应不同类型的 Result.error
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
@RestControllerAdvice
//捕获异常
public class CommonExceptionHandler {
@ExceptionHandler(Exception.class)
public Result<Object> handleException(Exception e) {
e.printStackTrace();
return Result.error(e.getMessage());
}
@ExceptionHandler(BusinessException.class)
public Result<Object> handleBusinessException(BusinessException e) {
e.printStackTrace();
ResponseEnum response = e.getResponse();
return Result.error(response);
}
}