ResponseBodyAdvice的作用:拦截Controller方法的返回值,统一处理返回值/响应体,一般用来统一返回格式,加解密,签名等等。使用后不需要在每一个接口返回值写返回体,统一返回结果,减少重复代码。
源码
1 2 3 4 5 6 7 8 9 10 11 12 13
| public interface ResponseBodyAdvice<T> {
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 @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"); 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
| 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; } }
|