全局异常处理1-ControllerAdvice+ExceptionHandler
本文使用 @ControllerAdvice + @ExceptionHandler 进行全局的 Controller 层异常处理。只要设计得当,就再也不用在 Controller 层进行 try-catch 了!
一、经典案例
需求:希望通过全局统一的异常处理将自定义错误码以json的形式发送给前端。
1 统一返回结果类 ApiResult
首先,定义一个统一结果返回类,最终需要将这个结果类的内容返回给前端。
package com.suncl.test2spring.exception;
import lombok.Data;
@Data
public class ApiResult {
private String code;
private String msg;
public ApiResult(String code, String msg) {
this.code = code;
this.msg = msg;
}
public ApiResult(ResultCode resultCode) {
this.code = resultCode.getCode();
msg = resultCode.getMsg();
}
}
2 错误码枚举类 ResultCode
package com.suncl.test2spring.exception;
public enum ResultCode {
/**
* 成功
*/
SUCCESS("200", "success"),
/**
* 未知错误
*/
BIZ_ERROR("505", "biz error"),
/**
* 未知错误
*/
UNKNOWN_ERROR("504", "unkonwn error");
/**
* 结果码
*/
private String code;
/**
* 结果码描述
*/
private String msg;
ResultCode(String code, String msg) {
this.code = code;
this.msg = msg;
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
}
3 自定义业务异常类 BizException
package com.suncl.test2spring.exception;
import lombok.extern.slf4j.Slf4j;
@Slf4j
public class BizException extends RuntimeException {
public BizException() {
}
public BizException(String message) {
super(message);
log.error(message);
}
public BizException(String message, Throwable cause) {
super(message, cause);
log.error(message);
}
public BizException(Throwable cause) {
super(cause);
}
}
4 定义全局异常处理类
- 通过 @ControllerAdvice 指定该类为 Controller 增强类。
- 通过 @ExceptionHandler 自定捕获的异常类型。
- 通过 @ResponseBody 返回 json 到前端。
package com.suncl.test2spring.exception;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 全局Controller层异常处理类-ControllerAdvice+ExceptionHandler 方式
*/
@ControllerAdvice
@Slf4j
public class GlobalExceptionResolver {
/**
* 处理所有不可知异常
*
* @param e 异常
* @return json结果
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public ApiResult handleException(Exception e) {
// 打印异常堆栈信息
log.error(e.getMessage(), e);
return new ApiResult(ResultCode.UNKNOWN_ERROR);
}
/**
* 处理所有业务异常
*
* @param e 业务异常
* @return json结果
*/
@ExceptionHandler(BizException.class)
@ResponseBody
public ApiResult handleOpdRuntimeException(BizException e) {
// 不打印异常堆栈信息
log.error(e.getMessage(),e);
return new ApiResult(ResultCode.BIZ_ERROR.getCode(),e.getMessage());
}
}
5 测试
上述写法对于系统中抛出的
throw new RuntimeException("未知异常出现了");
返回结果为 {"code":"504","msg":"unkonwn error"}
throw new BizException("用户id不可为空");
返回结果为 {"msg":"用户id不可为空","code":"505"}