一、common公共模块
1.common的作用
-
通用的代码、配置不应该散落在各个业务模块中,不利于维护与更新
-
一个大的系统,响应对象需要统一外层格式
-
各种业务设计与实现,可能会抛出各种各样的异常,异常信息的收集也应该做到统一
2.统一响应
提供统一响应的好处主要有两点:
1. 与前端和客户端保持统一,拥有统一的结构,方便前端和客户端的统一处理,特别是在程序出错的情况下,可以直接显示错误信息。
2. 日志结构的统一,我们经常会把程序的响应以日志的形式打印出来,所以。响应是统一的,日志的结构也能够保持统一。
统一响应的代码说明
@RestControllerAdvice 注解
Advice 在 Spring 中的含义就是对 XX 功能增强,RestControllerAdvice(ControllerAdvice)就是对控制器增强。之所以使用 RestControllerAdvice,是因为我们对外提供的都是 Rest 接口(json)。
我们需要对 Controller 返回的内容做一些额外的工作,即功能增强,就需要利用到这个注解。另外,这个注解提供了 basePackages 属性可以指定对特定 package 中的 Controller 生效。
ResponseBodyAdvice 接口
ResponseBodyAdvice 的作用是在响应体返回之前做一些自定义的处理工作。通常,我们会实现 ResponseBodyAdvice 接口,并包装统一的响应返回。接口的详细定义可以阅读 Spring 官网的解释: Spring ResponseBodyAdvice
- supports 方法
supports 的返回值是 boolean 类型,用于指定哪些 Controller 方法需要处理。我们当前的代码实现是标注了 IgnoreResponseAdvice 注解的类或者方法,统一响应不会生效。代码解释如下:
/**
* <h2>判断是否需要对响应进行处理</h2>
* @return false: 不需要处理; true: 需要处理
* */
@Override
@SuppressWarnings("all")
public boolean supports(MethodParameter methodParameter,
Class<? extends HttpMessageConverter<?>> aClass) {
// 如果当前方法所在的类标识了 IgnoreResponseAdvice 注解, 则不需要处理
if (methodParameter.getDeclaringClass().isAnnotationPresent(
IgnoreResponseAdvice.class
)) {
return false;
}
// 如果当前方法标识了 IgnoreResponseAdvice 注解, 则不需要处理
if (methodParameter.getMethod().isAnnotationPresent(
IgnoreResponseAdvice.class
)) {
return false;
}
// 对响应进行处理, 执行 beforeBodyWrite 方法
return true;
}
- beforeBodyWrite 方法
根据方法的名字可以知道,这个方法实现了在结果输出前的操作。这个方法的参数很多,我们只需要关注第一个:Object,这个就是原始的 Controller 返回的内容。我们也就是需要对它进行包装。代码解释如下:
/**
* <h2>响应返回之前的处理</h2>
* @param o 响应对象
* */
@Nullable
@Override
@SuppressWarnings("all")
public Object beforeBodyWrite(@Nullable Object o,
MethodParameter methodParameter,
MediaType mediaType,
Class<? extends HttpMessageConverter<?>> aClass,
ServerHttpRequest serverHttpRequest,
ServerHttpResponse serverHttpResponse) {
// 定义最终的返回对象
CommonResponse<Object> response = new CommonResponse<>(0, &