SpringBoot的@RestControllerAdvice定义全局异常处理
通常情况下,业务层抛出一些业务异常,controller层不能直接将异常堆栈信息返回给页面,而是将异常信息封装起来,将有用的信息提示出来,全局异常处理器就可以做这件事情。
@RestControllerAdvice:@ControllerAdvice和@ResponseBody的组合,捕捉 @Controller 和 @RestController 抛出的异常。
环境准备
1.创建springboot项目
2.引入依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
定义统一的响应对象
Result:
code:标识请求成功/请求失败
data:存放响应数据
message:存放响应提示信息
info:附加信息
requestId:traceId
import java.io.Serializable; /** * @author kerwin * @date 2021/7/22 18:07 */ // // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) // public class Result<T> implements Serializable { private static final long serialVersionUID = 1L; public static final transient String DEFAULT_SUCCESS_CODE = "0"; public static final transient String DEFAULT_ERROR_CODE = "-1"; private String code; private T data; private String message; private String info; private String requestId; public Result(T data) { this.data = data; this.code = "0"; this.message = "success"; } public Result() { this.code = "-1"; this.message = "failure"; } public boolean isSuccess() { return "0".equals(this.code); } public static Result success() { return new Result((Object)null); } public static Result success(Object data) { return new Result(data); } public static Result DefaultFailure(String msg) { Result result = new Result(); result.setCode("-1"); result.setMessage(msg); return result; } public String getCode() { return this.code; } public T getData() { return this.data; } public String getMessage() { return this.message; } public String getInfo() { return this.info; } public String getRequestId() { return this.requestId; } public Result<T> setCode(final String code) { this.code = code; return this; } public Result<T> setData(final T data) { this.data = data; return this; } public Result<T> setMessage(final String message) { this.message = message; return this; } public Result<T> setInfo(final String info) { this.info = info; return this; } public Result<T> setRequestId(final String requestId) { this.requestId = requestId; return this; } @Override public boolean equals(final Object o) { if (o == this) { return true; } else if (!(o instanceof Result)) { return false; } else { Result<?> other = (Result)o; if (!other.canEqual(this)) { return false; } else { label71: { Object this$code = this.getCode(); Object other$code = other.getCode(); if (this$code == null) { if (other$code == null) { break label71; } } else if (this$code.equals(other$code)) { break label71; } return false; } Object this$data = this.getData(); Object other$data = other.getData(); if (this$data == null) { if (other$data != null) { return false; } } else if (!this$data.equals(other$data)) { return false; } label57: { Object this$message = this.getMessage(); Object other$message = other.getMessage(); if (this$message == null) { if (other$message == null) { break label57; } } else if (this$message.equals(other$message)) { break label57; } return false; } Object this$info = this.getInfo(); Object other$info = other.getInfo(); if (this$info == null) { if (other$info != null) { return false; } } else if (!this$info.equals(other$info)) { return false; } Object this$requestId = this.getRequestId(); Object other$requestId = other.getRequestId(); if (this$requestId == null) { if (other$requestId == null) { return true; } } else if (this$requestId.equals(other$requestId)) { return true; } return false; } } } protected boolean canEqual(final Object other) { return other instanceof Result; } @Override public int hashCode() { boolean PRIME = true; int result = 1; Object $code = this.getCode(); result = 0; result = result * 59 + ($code == null ? 43 : $code.hashCode()); Object $data = this.getData(); result = result * 59 + ($data == null ? 43 : $data.hashCode()); Object $message = this.getMessage(); result = result * 59 + ($message == null ? 43 : $message.hashCode()); Object $info = this.getInfo(); result = result * 59 + ($info == null ? 43 : $info.hashCode()); Object $requestId = this.getRequestId(); result = result * 59 + ($requestId == null ? 43 : $requestId.hashCode()); return result; } @Override public String toString() { return "Result(code=" + this.getCode() + ", data=" + this.getData() + ", message=" + this.getMessage() + ", info=" + this.getInfo() + ", requestId=" + this.getRequestId() + ")"; } }
定义异常场景,例如业务异常、转换异常等
public class BusinessException extends RuntimeException { /** * */ private static final long serialVersionUID = -2375722139644724409L; public BusinessException() { } public BusinessException(String message, Throwable cause) { super(message, cause); } public BusinessException(String message) { super(message); } public BusinessException(Throwable cause) { super(cause); } }
定义异常处理控制器
@RestControllerAdvice() @Slf4j @Order(Ordered.HIGHEST_PRECEDENCE) //加载优先级 @SuppressWarnings("all") public class ExceptionHandlerController { @ExceptionHandler({BusinessException.class}) @ResponseBody public Result<String> businessExceptionHandler(HttpServletRequest req, BusinessException e) throws Exception { Result<String> error = new Result<>(); error.setCode(Result.DEFAULT_ERROR_CODE); error.setMessage(e.getMessage()); error.setRequestId(MDC.get("traceId")); return error; } /** * 统一处理系统异常, json 格式返回 * * @param t * 系统异常 * @return 带错误码和描述的 json */ @ExceptionHandler(Throwable.class) public Result<Void> handleThrowable(Throwable t, HttpServletRequest request) { log.error(("handleThrowable requestUri " + request.getRequestURI() + "system error"), t); return new Result<Void>().setMessage("系统繁忙,请稍后再试").setInfo("系统繁忙,请稍后再试"); } }
测试
/** * @author kerwin * @date 2021/7/22 22:11 */ @RestController public class Test { @GetMapping("test/{name}") public Result<Void> test(@PathVariable("name") String name){ //模拟service抛出异常 throw new BusinessException("fail"); } }
请求此接口,返回响应:
符合预期,一个简单的异常处理器就完成啦。