Springboot-cli 开发脚手架系列
简介
-
为什么要用全局异常处理
可以定义返回的统一json结构,前端或者其他服务请求本服务的接口时,该接口需要返回对应的json数据,一般该服务只需要返回请求者需要的参数即可,但是在实际项目中,我们需要封装更多的信息,比如状态码code、相关信息msg等。这里我们只保留状态码code和异常信息msg。
-
@ControllerAdvice
配合@ExceptionHandler
实现全局异常处理。@ControllerAdvice ,很多初学者可能都没有听说过这个注解,实际上,这是一个非常有用的注解,顾名思义,这是一个增强的 Controller。使用这个 Controller ,可以实现三个方面的功能:全局异常处理、全局数据绑定、全局数据预处理
-
@RestControllerAdvice
功能和@ControllerAdvice
一样,本质上等于@ControllerAdvice
+@ResponseBody
1. 环境配置
- pom
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. 封装自定义异常
MyException
,我们只需要重写抽象类RuntimeException
即可
/**
* 自定义异常
*
* @author ding
*/
@EqualsAndHashCode(callSuper = true)
@Data
public class MyException extends RuntimeException {
private static final long serialVersionUID = 1L;
private String msg;
private Integer code = 200;
public MyException(String msg) {
super(msg);
this.msg = msg;
}
public MyException(String msg, Throwable e) {
super(msg, e);
this.msg = msg;
}
public MyException(String msg, int code) {
super(msg);
this.msg = msg;
this.code = code;
}
public MyException(String msg, int code, Throwable e) {
super(msg, e);
this.msg = msg;
this.code = code;
}
}
3. 定义全局通用返回
ResponseResult
统一返回格式,便于前端处理数据
/**
* 通用响应体
*
* @author qiding
*/
@Data
@Accessors(chain = true)
public class ResponseResult<T> implements Serializable {
private static final long serialVersionUID = -1L;
private Integer code;
private String message;
private T data;
/**
* http默认构造
*/
public ResponseResult() {
super();
this.code = RespCode.OK.code;
this.message = RespCode.ERROR.message;
}
public ResponseResult(T data) {
super();
this.code = RespCode.OK.code;
this.message = RespCode.OK.message;
this.data = data;
}
public ResponseResult(RespCode respCode) {
super();
this.code = respCode.getCode();
this.message = respCode.getMessage();
}
public ResponseResult(Integer code, String message) {
super();
this.code = code;
this.message = message;
}
public ResponseResult(Integer code, String message, T data) {
super();
this.code = code;
this.message = message;
this.data = data;
}
public enum RespCode {
/**
* 业务码
*/
OK(20000, "请求成功"),
MY_ERROR(20433, "自定义异常"),
ERROR(20400, "请求失败");
RespCode(int code, String message) {
this.code = code;
this.message = message;
}
private final int code;
private final String message;
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
}
4. 编写全局异常处理器
ControllerExceptionHandler
用于捕获异常全局处理
/**
* 全局异常捕获
* 若用 @RestControllerAdvice 替换 @ControllerAdvice 则可省略 @ResponseBody
*
* @author ding
*/
@ControllerAdvice
@Slf4j
public class ControllerExceptionHandler {
/**
* 捕获我们定义的异常
*/
@ExceptionHandler(MyException.class)
@ResponseBody
public ResponseResult<String> handleUserNotExistsException(MyException e) {
log.error("捕获到自定义异常:{}", e.getMessage());
return new ResponseResult<>(ResponseResult.RespCode.MY_ERROR.getCode(), e.getMessage());
}
/**
* 捕获其它异常
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public ResponseResult<String> handlerNoFoundException(Exception e) {
log.error(e.getMessage(), e);
return new ResponseResult<>(ResponseResult.RespCode.ERROR);
}
}
5. 实战演示
- 编写测试接口
@RestController
public class IndexController {
@GetMapping("/")
public ResponseResult<String> get() {
return new ResponseResult<>("模拟成功获取数据");
}
/**
* 自定义异常捕获
*/
@GetMapping("/err")
public ResponseResult<String> error() {
throw new MyException("模拟异常", 4004);
}
/**
* 其它异常捕获
*/
@GetMapping("/err2")
public ResponseResult<String> error2() {
int i = 1 / 0;
return new ResponseResult<>("OK");
}
}
-
浏览器访问
http://localhost:9999/
模拟成功获取数据
-
浏览器访问
http://localhost:9999/err
模拟自定义异常捕获
-
浏览器访问
http://localhost:9999/err2
模拟其它异常捕获
后台虽然报错,但异常已被捕获,所以不影响我们返回正常的JSON体
6. 源码分享
- Springboot-cli开发脚手架,集合各种常用框架使用案例,完善的文档,致力于让开发者快速搭建基础环境并让应用跑起来。
- 项目源码github地址
- 项目源码国内gitee地址