@RestControllerAdvice
注解@RestControllerAdvice用法途-优快云博客
需求:
当http请求的时候,自动处理异常,并返回给前端。
异常分为:服务器内部异常Exception, 自定义业务异常
异常格式例如:
{"msg":"服务器内部异常","code":500,"success":false,"data":null}
实现思路:
定义vo:
确定返回的json格式。
@JsonInclude
public class ResultVo<T> implements Serializable {
private static final long serialVersionUID = -872079464102668214L;
@Schema(description = "返回消息")
private String msg;
@Schema(description = "返回码")
private Integer code;
@Schema(description = "是否成功")
private Boolean success;
@Schema(description = "返回数据")
private transient T data;
public ResultVo() {
}
@JsonCreator(mode = Mode.PROPERTIES)
public ResultVo(@JsonProperty("msg") String msg, @JsonProperty("code") Integer code,
@JsonProperty("success") Boolean success, @JsonProperty("data") T data) {
this.msg = msg;
this.code = code;
this.success = success;
this.data = data;
}
public static <T> ResultVo<T> create(ResponseCodeEnum codeEnum, Boolean success, T data) {
return new ResultVo<>(codeEnum.getMsg(), codeEnum.getCode(), success, data);
}
public static <T> ResultVo<T> create(ResponseCodeEnum codeEnum, String msg, Boolean success, T data) {
return new ResultVo<>(msg, codeEnum.getCode(), success, data);
}
public static <T> ResultVo<T> create(String msg, Integer code, Boolean success, T data) {
return new ResultVo<>(msg, code, success, data);
}
public static <T> ResultVo<T> createSuccess(T data, String msg) {
return create(SUCCESS, msg, true, data);
}
public static <T> ResultVo<T> createSuccess(T data) {
return create(SUCCESS, true, data);
}
public String getMsg() {
return this.msg;
}
public ResultVo<T> setMsg(String msg) {
this.msg = msg;
return this;
}
public Integer getCode() {
return this.code;
}
public ResultVo<T> setCode(Integer code) {
this.code = code;
return this;
}
public Boolean getSuccess() {
return this.success;
}
public ResultVo<T> setSuccess(Boolean success) {
this.success = success;
return this;
}
public T getData() {
return this.data;
}
public ResultVo<T> setData(T data) {
this.data = data;
return this;
}
@Override
public String toString() {
return "ResultVo{" +
"msg=\"" + msg + '\"' +
", code=" + code +
", success=" + success +
", data=" + data +
'}';
}
}
定义异常代码
public enum ResponseCodeEnum {
/**
* 成功代码
*/
SUCCESS(0, "success"),
/**
* http成功
*/
HTTP_SUCCESS(200, "success"),
/**
* 异常码,http相关
*/
FORBIDDEN(403, "禁止访问"),
NOT_FOUND(404, "资源不存在"),
REQUIRE_ACCESS(407, "要求身份验证"),
INTERNAL_EXCEPTION(500, "服务器内部异常"),
/**
* 业务异常码
*/
private final int code;
private final String msg;
ResponseCodeEnum(int code, String msg) {
this.code = code;
this.msg = msg;
}
public int getCode() {
return this.code;
}
public String getMsg() {
return this.msg;
}
}
异常处理:
处理三类,
Exception 一般为controller抛出的代码异常
BusinessException 自定义业务异常
BindException net异常
@RestControllerAdvice
public class GlobalRestRequestExceptionHandler {
private static final String EX_MSG = "服务内部错误!";
private static final Logger log = LoggerFactory.getLogger(GlobalRestRequestExceptionHandler.class);
@ExceptionHandler(value = BusinessException.class)
public ResultVo<?> businessExceptionHandler(HttpServletRequest request, BusinessException exception) {
log.error("[GlobalRestRequestExceptionHandler.businessExceptionHandler] url is {}",
request.getRequestURI(), exception);
return new ResultVo<>(exception.getMessage(), exception.getCode(), false, null);
}
/**
* 参数校验错误
*
* @param request 请求
* @param exception 异常
* @return 通用返回
*/
@ExceptionHandler(value = BindException.class)
public ResultVo<?> methodArgumentNotValidException(HttpServletRequest request, BindException exception) {
BindingResult result = exception.getBindingResult();
String message = null;
//组装校验错误信息
if (result.hasErrors()) {
List<ObjectError> list = result.getAllErrors();
StringBuilder errorMsgBuffer = new StringBuilder();
for (ObjectError error : list) {
if (error instanceof FieldError) {
FieldError errorMessage = (FieldError) error;
errorMsgBuffer.append(errorMessage.getDefaultMessage()).append(",");
}
}
//返回信息格式处理
message = errorMsgBuffer.substring(0, errorMsgBuffer.length() - 1);
}
if (message == null || message.isEmpty()) {
message = EX_MSG;
}
log.error("[GlobalRestRequestExceptionHandler.methodArgumentNotValidException] url: {}, msg: {}",
request.getRequestURI(), message);
return new ResultVo<>(message, 500, false, null);
}
@ExceptionHandler(value = Exception.class)
public ResultVo<?> exceptionHandler(HttpServletRequest request, Exception exception) {
log.error("[GlobalRestRequestExceptionHandler.exceptionHandler] url: {}",
request.getRequestURI(), exception);
return ResultVo.create(INTERNAL_EXCEPTION, false, null);
}
}
业务异常处理:
定义异常基类
目录
如何使用
try{}catch{}使用
业务判断 直接调用
return ResultVo.create(RULE_NOT_EXIST, false, false);
改进
业务异常和系统异常分包要明确,可以专门建一个包来放业务异常的枚举,一个模块一个异常枚举类。