废话不多说,直接开搞
1.安装Lombok插件,JDK1.8
2.本文中使用的统一返回数据类引入的是阿里考拉
com.alibaba.cola
cola-component-domain-starter /version>
自定义枚举类有两个属性,errorCode 错误码,errorValue 错误原因。在后面自定义异常中会使用到此枚举类。
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* 异常枚举类
* @author zhouzhou
*/
@Getter
@AllArgsConstructor
public enum ErrorEnum {
/**
* 用户信息相关
*/
USER_NOT_EXIST_ERROR("20001","未查询到用户信息"),
USER_NOT_LOGIN_ERROR("20002","用户登录信息有误,请重新登录"),
;
private String errorCode;
private String errorValue;
}
自定义异常基类继承的也是RuntimeException,属于运行时异常,其中有两个成员变量,聪明的小伙伴是不是一眼就看出来这两个变量的含义了。
import lombok.Data;
/**
* 业务类自定义异常类
*/
@Data
public class BusinessException extends RuntimeException{
private String errorCode;
private String errorValue;
public BusinessException(String errorCode, String errorValue){
super(errorValue);
this.errorCode = errorCode;
this.errorValue = errorValue;
}
}
继承BusinessException,主要是用来区分是哪部分业务抛出的异常,也可以将类名改为业务模块名,比如UserException,这样在异常信息补获的时候可以更清晰的知道是哪部分业务抛出的异常。
import com.pailifan.meta.client.base.BusinessException;
import com.pailifan.meta.client.enums.ErrorEnum;
/**
* 自定义异常
* @author zhouzhou
*/
public class CustomerException extends BusinessException {
public CustomerException(ErrorEnum ErrorEnum){
super(ErrorEnum.getErrorCode(), ErrorEnum.getErrorValue());
}
}
------------------重点来了-----------------
在spring 3.2中,新增了@ControllerAdvice 注解,可以用于定义@ExceptionHandler、@InitBinder、@ModelAttribute,并应用到所有@RequestMapping中。参考:@ControllerAdvice 文档
import com.alibaba.cola.dto.Response;
import com.alibaba.cola.dto.SingleResponse;
import com.alibaba.cola.exception.BizException;
import com.pailifan.meta.client.base.BusinessException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
* @Description
* @Author zhouzhou
**/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
/**
* @description: 捕获异常信息
* @param: [e]
* @return: com.alibaba.cola.dto.Response
* @author zhouzhou
* @date: 2022/11/7 10:54
*/
@ResponseBody
@ExceptionHandler(BusinessException.class)
public Response handleBizException(BusinessException e) {
log.error("BusinessException,code={},value={}", e.getErrorCode(),e.getErrorValue());
return SingleResponse.buildFailure(e.getErrorCode(), e.getErrorValue());
}
@ResponseBody
@ExceptionHandler(Exception.class)
public Response handleException(Exception e) {
log.error("Exception", e);
return SingleResponse.buildFailure(String.valueOf(HttpStatus.INTERNAL_SERVER_ERROR.value()), "系统异常");
}
}
在业务代码使用中,如果校验条件不满足,可以直接使用throw抛出自定义异常信息,不用频繁的写try catch和手动拼接返回信息。
if(判断条件){
throw new CustomerException(ErrorEnum.USER_NOT_EXIST_ERROR);
}
{
"success": false,
"errCode": "20002",
"errMessage": "用户登录信息有误,请重新登陆",
"data": null
}
http状态还是200,前端只需要根据success判断请求是否成功,如果失败可以直接弹框提示errMessage信息。成功状态下从data中获取数据
在开发过程中,后端接口返回的数据结构应该是统一且固定的,不应该因为后端发生异常而导致向前端返回的数据结构发生变化,这样就减少了前段的校验工作,只需要一套公共代码就能解析固定的数据结构。
而自定义异常是为了在发生错误时,可以从错误信息中更好更快的找到有用的提示信息。也可以通过异常信息快速的定位业务模块。