优雅哥 SpringBoot 2.7.2 实战基础 - 08 - 全局异常处理及参数校验
前后端分离开发非常普遍,后端处理业务,为前端提供接口。服务中总会出现很多运行时异常和业务异常,本文主要讲解在 SpringBoot 实战中如何进行异常统一处理和请求参数的校验。
1 异常统一处理
所有异常处理相关的类,咱们都放到 com.yygnb.demo.common
包中。
当后端发生异常时,需要按照一个约定的规则(结构)返回给前端,所以先定义一个发生异常时固定的结构。
1.1 错误响应结构
发生异常时的响应结构约定两个字段:code——错误编码;msg——错误消息。创建类:
com.yygnb.demo.common.domain.ErrorResult
:
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ErrorResult implements Serializable {
private static final long serialVersionUID = -8738363760223125457L;
/**
* 错误码
*/
private String code;
/**
* 错误消息
*/
private String msg;
public static ErrorResult build(ErrorResult commonErrorResult, String msg) {
return new ErrorResult(commonErrorResult.getCode(), commonErrorResult.getMsg() + " " + msg);
}
}
1.2 通用错误响应常量
有些异常返回的 ErrorResult 是一样的,如参数校验错误、未查询到对象、系统异常等,可以定义一些错误响应的常量:
com.yygnb.demo.common.exception.DefaultErrorResult
:
public interface DefaultErrorResult {
ErrorResult SYSTEM_ERROR = new ErrorResult("C00001", "系统异常");
ErrorResult CUSTOM_ERROR = new ErrorResult("C99999", "自定义异常");
ErrorResult PARAM_BIND_ERROR = new ErrorResult("C00003", "参数绑定错误:");
ErrorResult PARAM_VALID_ERROR = new ErrorResult("S00004", "参数校验错误:");
ErrorResult JSON_PARSE_ERROR = new ErrorResult("S00005", "JSON转换异常");
ErrorResult CODE_NOT_FOUND = new ErrorResult("S00006", "根据编码没有查询到对象");
ErrorResult ID_NOT_FOUND = new ErrorResult("S00007", "根据ID没有查询到对象");
}
1.3 通用异常类定义
定义一个通用的异常类 CommonException
,继承自 RuntimeException
,当程序中捕获到编译时异常或业务异常时,就抛出这个通用异常,交给全局来处理。(随着业务复杂度的增加,可以细分自定义异常,如 AuthException
、UserException
、CouponException
等,让这些细分异常都继承自 CommonException
。)
com.yygnb.demo.common.exception.CommonException
:
@EqualsAndHashCode(callSuper = true)
@Data
public class CommonException extends RuntimeException {
protected ErrorResult errorResult;
public CommonException(String message) {
super(message);
}
public CommonException(String message, Throwable cause) {
super(message, cause);
}
public CommonException(Throwable cause) {
super(cause);
}
protected CommonException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public CommonException(String code, String msg) {
super(msg + "(" + code + ")");
this