首页  编辑  

SpringBoot使用ResponseBodyAdvice对Controller返回内容统一包装处理

Tags: /Java/   Date Created:
一般对Controller返回的是AJAX内容的JSON,Application内每个Controller返回的数据对象可能都不相同,但是我们可能想返回统一的数据格式,例如:
{
  "code": 0,
  "message": "success",
  "data": { ... }
}
返回的数据内容在data中。
可以使用 ResponseBodyAdvice 实现:

统一包装处理

Spring 中提供了一个类 ResponseBodyAdvice ,能帮助我们实现上述需求

ResponseBodyAdvice 是对 Controller 返回的内容在 HttpMessageConverter 进行类型转换之前拦截,进行相应的处理操作后,再将结果返回给客户端。那这样就可以把统一包装的工作放到这个类里面。

public interface ResponseBodyAdvice<T{  
    boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType);  
  
    @Nullable  
    beforeBodyWrite(@Nullable T body, MethodParameter returnType, MediaType selectedContentType, Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request, ServerHttpResponse response);  
}  

  • supports:判断是否要交给 beforeBodyWrite 方法执行,ture:需要;false:不需要
  • beforeBodyWrite:对 response 进行具体的处理
// 如果引入了swagger或knife4j的文档生成组件,这里需要仅扫描自己项目的包,否则文档无法正常生成  
@RestControllerAdvice(basePackages = "com.example.demo")  
public class ResponseAdvice 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) {  
        // 提供一定的灵活度,如果body已经被包装了,就不进行包装  
        if (body instanceof Result) {  
            return body;  
        }  
        return Result.success(body);  
    }  
}  

经过这样改造,既能实现对 Controller 返回的数据进行统一包装,又不需要对原有代码进行大量的改动