最近遇到了统一异常处理的问题,当后端异常时,需要按照统一的格式向前端发送信息。
1、首先,需要规定返回数据的格式,这里新构建了返回格式类JsonResponse。
//省略get set方法
public class JsonResponse<T> {
private String code;
private String msg;
//data表示需要返回至上一层的数据
private T data;
//定义不包含data构造函数,意思是不需要data,但是需要自定义code和msg
public JsonResponse(String code, String msg) {
this.code = code;
this.msg = msg;
}
//定义包含data的构造函数,默认msg为成功
public JsonResponse(T data) {
this.data = data;
this.code = "0";
this.msg = "success";
}
//编写成功的静态方法,调用第二个构造函数,但传参为null
public static JsonResponse<String> success(){
return new JsonResponse<>(null);
}
//编写成功的静态方法,调用第二个构造函数,但传参为datas
public static JsonResponse<String> success(String data){
return new JsonResponse<>(data);
}
//编写失败的静态方法,调用第一个构造函数,表示失败后不用返回。是固定的状态码和提示。
public static JsonResponse<String> fail(){
return new JsonResponse<>("1","fail!");
}
//编写失败的静态方法,不用返回。但可以自定义状态码和提示信息。
public static JsonResponse<String> fail(String code , String msg){
return new JsonResponse<>(code,msg);
}
}
JsonResponse类中,包含三个需要返回的参数:code码、message提示消息、data数据。同时还定义了两个构造函数,分别携带data数据以及不携带data数据,最后,还定义了success、fail方法。这样不论是正常情况下还是异常情况下,都能够保证返回数据的一致性。
在正常情况下,需要重点关注data,即泛型就是data,return new JsonResponse<T>() 即可,这里的T就是需要返回的Java对象。
2、对于异常情况,就需要关注code码以及相应的异常信息。这里的异常主要分为两类(与运行时异常和非运行时异常不同,个人定义为主动抛出异常和被动抛出异常,主动异常是正常逻辑判断中的异常,需要显式处理;而被动抛出异常是本不应该的异常),对于主动抛出异常,定义了一个异常处理类:
public class ConditionException extends RuntimeException {
public static final Long serialVersionUID = 1L ;
private String code;
//全参构造函数,自定义code
public ConditionException(String name , String code){
super(name);
this.code = code;
}
//半参构造函数,固定code
public ConditionException(String name){
super(name);
this.code = "500";
}
//省略get set
}
ConditionException需要继承RunTimeException,主要接住主动异常,并关注其中的code码和message信息,例子如下:
//获取密码并使用RSA解密的过程,并主动抛出异常
String password = user.getPassword();
String rawPassword;
try {
rawPassword = RSAUtil.decrypt(password);
} catch (Exception e) {
throw new ConditionException("解密失败!");
}
3、spring框架中的@ControllerAdvice和@ExceptionHandle能够统一处理异常,具体如下:
@ControllerAdvice
@Order(value = Ordered.HIGHEST_PRECEDENCE)
public class CommonGlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
public JsonResponse<String> commonExceptionHandler(HttpServletRequest request , Exception e){
String errMsg = e.getMessage();
if (e instanceof ConditionException){
String code = ((ConditionException)e).getCode();
return new JsonResponse<>(code,errMsg);
}else{
return new JsonResponse<>("500",errMsg);
}
}
}
在ExceptionHandle类中,通过判断异常类型,如果是主动构建的ConditionException异常类,那么就获取其中的code等信息,然后new JsonResponse。这样就巧妙的将三者结合起来,最终使得正常和异常的信息均遵循统一的格式。