零、背景
很多时候我们调用接口并不是需要接口返回的所有信息;
就像查询数据库很少使用 select * from table; 一样;
为了使现有的存储结构以及代码逻辑改动最少
想办法在最外层的接口对返回的对象进行精简
目的使为了提高接口性能:减少 RPC 传输时间、节省网络带宽、节省序列化开销
一、方案
- 直接创建一个对象,根据入参传入的所需字段,写一堆 if else 进行 get set;
- 使用序列化工具,转为类似 Map 结构,取值拼装;
- 使用 BeanWrapper 操作对象;
前面两种比较呆板,属于定制化开发;
二、实践
Spring BeanWrapper 方案处理非集合对象比较完美,输出对象小不少;
基本数据类型有默认值,无法去除,不过这种对大小影响不大;
完整代码:github.com
1 | public static void main(String[] args) { |
输出 src:
1 | { |
输出dst
1 | { |
三、缺点
目前 Spring BeanWrapper 处理集合类型比较费劲,需要告知一个个具体的路径
比如:productInfos[1].name
如果能做到 productInfos[any].name 这种,然后取出所有 index 的属性,就比较完美
(目前解决方法:通过自定义处理,遇到 any 标识,自动补全所有 index 的 key 即可,只是不那么优雅)
缺陷原因:内部逻辑直接用 key 转换为 index ,没有 any 逻辑。
1 | else if (value instanceof List) { |
代码位置:org.springframework.beans.AbstractNestablePropertyAccessor#getPropertyValue
四、参考
Spring 官方文档:Bean Manipulation and the BeanWrapper