@RestControllerAdvice 注解

Advice 在 Spring 中的含义就是对 XX 功能增强,RestControllerAdvice(ControllerAdvice)就是对控制器增强。之所以使用 RestControllerAdvice,是因为我们对外提供的都是 Rest 接口(json)。
我们需要对 Controller 返回的内容做一些额外的工作,即功能增强,就需要利用到这个注解。另外,这个注解提供了 basePackages 属性可以指定对特定 package 中的 Controller 生效。
**

ResponseBodyAdvice 接口

ResponseBodyAdvice 的作用是在响应体返回之前做一些自定义的处理工作。通常,我们会实现 ResponseBodyAdvice 接口,并包装统一的响应返回。接口的详细定义可以阅读 Spring 官网的解释: Spring ResponseBodyAdvice
**

ResponseBodyAdvice接口的supports 方法

supports 的返回值是 boolean 类型,用于指定哪些 Controller 方法需要处理。我们当前的代码实现是标注了 IgnoreResponseAdvice 注解的类或者方法,统一响应不会生效。代码解释如下:

  1. /**
  2. * <h2>判断是否需要对响应进行处理</h2>
  3. * @return false: 不需要处理; true: 需要处理
  4. * */
  5. @Override
  6. @SuppressWarnings("all")
  7. public boolean supports(MethodParameter methodParameter,
  8. Class<? extends HttpMessageConverter<?>> aClass) {
  9. // 如果当前方法所在的类标识了 IgnoreResponseAdvice 注解, 则不需要处理
  10. if (methodParameter.getDeclaringClass().isAnnotationPresent(IgnoreResponseAdvice.class)) {
  11. return false;
  12. }
  13. // 如果当前方法标识了 IgnoreResponseAdvice 注解, 则不需要处理
  14. if (methodParameter.getMethod().isAnnotationPresent(IgnoreResponseAdvice.class)) {
  15. return false;
  16. }
  17. // 对响应进行处理, 执行 beforeBodyWrite 方法
  18. return true;
  19. }

**

beforeBodyWrite 方法

根据方法的名字可以知道,这个方法实现了在结果输出前的操作。这个方法的参数很多,我们只需要关注第一个:Object,这个就是原始的 Controller 返回的内容。我们也就是需要对它进行包装。代码解释如下:

  1. /**
  2. * <h2>响应返回之前的处理</h2>
  3. * @param o 响应对象
  4. * */
  5. @Nullable
  6. @Override
  7. @SuppressWarnings("all")
  8. public Object beforeBodyWrite(@Nullable Object o,
  9. MethodParameter methodParameter,
  10. MediaType mediaType,
  11. Class<? extends HttpMessageConverter<?>> aClass,
  12. ServerHttpRequest serverHttpRequest,
  13. ServerHttpResponse serverHttpResponse) {
  14. // 定义最终的返回对象
  15. CommonResponse<Object> response = new CommonResponse<>(0, "");
  16. // 如果 o 是 null, response 不需要设置 data
  17. if (null == o) {
  18. return response;
  19. // 如果 o 已经是 CommonResponse 类型, 强转即可
  20. } else if (o instanceof CommonResponse) {
  21. response = (CommonResponse<Object>) o;
  22. // 否则, 把响应对象作为 CommonResponse 的 data 部分
  23. } else {
  24. response.setData(o);
  25. }
  26. return response;
  27. }

如果我们对 Controller 返回的结果的处理过程比较复杂,那么根据处理的分类,可以指定多个ResponseBodyAdvice,并使用 @Order 指定处理顺序。
**