前言
最近在优化自己之前基于Spring AOP的统一响应体的实现方案。
什么是统一响应体呢?在目前的前后端分离架构下,后端主要是一个RESTful API的数据接口。
但是HTTP的状态码数量有限,而随着业务的增长,HTTP状态码无法很好地表示业务中遇到的异常情况。
那么可以通过修改响应返回的JSON数据,让其带上一些固有的字段,例如以下这样的
{
"code": 10000,
"msg": "success",
"data": {
"id": 2,
"name": "test"
}
}
其中关键属性的用途如下:
code为返回结果的状态码
msg为返回结果的消息
data为返回的业务数据
这3个属性为固有属性,每次响应结果都会有带有它们。
需求
希望实现一个能够代替基于AOP的实现方案,需要满足以下几点:
原有的基于AOP的实现方案需要Controller的返回类型为Object,需要新方案不限制返回类型
原有的基于AOP的实现方案需要通过切面表达式+注解控制切点的Controller(注解的包名修改会导致切面表达式的修改,即需要修改两处地方),需要新方案能够基于注解,而不需要修改切面表达式
方案思路
基于上述的需求,选择使用Spring的Controller增强机制,其中关键的类为以下3个:
@ControllerAdvice:类注解,用于指定Controller增强处理器类。
ResponseBodyAdvice:接口,实现后beforeBodyWrite()方法后可以对响应的body进行修改,需要结合@ControllerAdvice使用。
@ExceptionHandler:方法注解,用于指定异常处理方法,需要结合@ControllerAdvice和@ResponseBody使用。
示例关键代码
本示例使用的Spring Boot版本为2.1.6.RELEASE,同时需要开发工具安装lombok插件
引入依赖
org.springframework.boot
spring-boot-starter-web
org.projectlombok
lombok
true
org.springframework.boot
spring-boot-starter-test
test
统一响应体
Controller增强后统一响应体对应的对象
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
/**
* 统一的公共响应体
* @author NULL
* @date 2019-07-16
*/
@Data
@AllArgsConstructor
public class ResponseResult implements Serializable {
/**
* 返回状态码
*/
private Integer code;
/**
* 返回信息
*/
private String msg;
/**
* 数据
*/
private O