前言
最近在优化自己之前基于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
插件
引入依赖
<dependencies>
<!--web-starter-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>