ResponseBodyAdvice统一处理返回值/响应体

ResponseBodyAdvice的作用:拦截Controller方法的返回值,统一处理返回值/响应体,一般用来统一返回格式,加解密,签名等等。使用后不需要在每一个接口返回值写返回体,统一返回结果,减少重复代码。

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface ResponseBodyAdvice<T> {
/**
* 是否支持advice功能
* true 支持,false 不支持
*/
boolean supports(MethodParameter var1, Class<? extends HttpMessageConverter<?>> var2);

/**
* 对返回的数据进行处理
*/
@Nullable
T beforeBodyWrite(@Nullable T var1, MethodParameter var2, MediaType var3, Class<? extends HttpMessageConverter<?>> var4, ServerHttpRequest var5, ServerHttpResponse var6);
}

源码分析

ResponseBodyAdvice 接口是在 Controller 执行 return 之后,在 response 返回给客户端之前,执行的对 response 的一些处理,可以实现对 response 数据的一些统一封装或者加密等操作。

(1)supports —— 判断是否要执行beforeBodyWrite方法,true为执行,false不执行 —— 通过supports方法,我们可以选择哪些类或哪些方法要对response进行处理,其余的则不处理。

(2)beforeBodyWrite —— 对 response 处理的具体执行方法。

在supports中返回true,可以对所有返回值处理。

示例

Controller层代码
1
2
3
4
5
6
7
8
@RestController //此注解包含@ResponseBody注解
@RequestMapping("/mp")
public class ResponseBodyAdviceController {
@RequestMapping(value = "/hello", method = RequestMethod.GET)
public int hello() {
return 5;
}
}
ResponseBodyAdvice实现类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@RestControllerAdvice
public class RestResultWrapper implements ResponseBodyAdvice<Object> {
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return true;
}

@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
ServerHttpResponse response) {

//定义一个统一的返回类
RestResult responseResult = new RestResult( "0", body, "success");
//如果handler处理类的返回类型是String(即控制层的返回值类型),为了保证一致性,这里需要将ResponseResult转回去
if(body instanceof String) {
return JSON.toJSONString(responseResult);
}
//封装后的数据返回到前端页面
return JSONObject.toJSON(responseResult);
}
}

@RestControllerAdvice@RestController注解的增强,可以实现三个方面的功能:

  • 全局异常处理

  • 全局数据绑定

  • 全局数据预处理

1
2
3
if(o instanceof String){
return objectMapper.writeValueAsString(ResultData.success(o));
}

如果Controller直接返回String的话,SpringBoot是直接返回,故我们需要手动转换成json。

公共返回类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// 统一返回Rest风格的数据结构
public class RestResult<T> implements Serializable {
private String code = "2000";
// 成功时返回的数据,失败时返回具体的异常信息
private T data;
// 请求失败返回的提示信息,给前端进行页面展示的信息
private String message ;

public RestResult() {
}

@Override
public String toString() {
return "RestResult{" +
"code='" + code + '\'' +
", data=" + data +
", message=" + message +
'}';
}

public RestResult(String code, T data, String message) {
this.code = code;
this.data = data;
this.message = message;
}
}