非标类型导致Dubbo接口出入参异常的本质 | 得物技术
目录
一、概述
二、问题是什么?
1. DTO中声明了类型模糊的字段
2. DTO中赋值了非标集合类型数据
三、为什么会有这个问题?
1. 对端(另一个进程)不存在的类型
2. 无法通过反射实例化的类型
四、怎么处理这个问题?
1. 调整序列化方案
2. 包容它、迁就它
2.1 标准库工具类
2.2 lang3库工具类
2.3 guava库工具类
五、总结
一
概述
二
问题是什么?
接口使用的是DubboRPC; 接口使用的是Protostuff序列化; DTO中声明了类型模糊的字段; 类型模糊的字段赋值了非标集合类型数据。
DTO中声明了类型模糊的字段
例2
例3
你看到都迷糊,更别提代码了。
DTO中赋值了非标集合类型数据
io.protostuff.CollectionSchema.MessageFactories
三
为什么会有这个问题?
不管是json这种文本格式,还是Protostuff这种二进制格式,序列化产物(byte[ ])在逻辑结构上是相似的~
对端(另一个进程)不存在的类型
无法通过反射实例化的类型
技术上来说,所有类都有手段进行实例化,比如使用sun.misc.Unsafe#allocateInstance,只是因为绕过了构造方法,实例化出来的类状态是不完整的,不能正常使用。
四
怎么处理这个问题?
调整序列化方案
包容它、迁就它
你一定想问:为什么中间件同学不能向前一步cover这个问题,还得我们使用者注意,中间件同学的担当、责任感呢?
您的拷问很有道理!但是没有办法,或许Protostuff是为了追求极致的性能而完全抛弃了代码可读性、可维护性,中间件同学完全改不动、不敢改。
标准库工具类
ArrayList<Integer> list = Lists.newArrayList(1, 2, 3);
List<Integer> obj3 = list.subList(1, 2);
ArrayList<Integer> list = Lists.newArrayList(1, 2, 3);
List<Integer> obj3 = list.subList(1, 2);
List<Integer> obj4 = new ArrayList<>(obj3);
lang3库工具类
List<Integer> list = new FastArrayList(1, 2, 3);
List<Integer> obj3 = list.subList(1, 2);
ArrayList<Integer> list = Lists.newArrayList(1, 2, 3);
List<Integer> obj3 = list.subList(1, 2);
List<Integer> obj4 = new ArrayList<>(obj3);
guava库工具类
ArrayList<Integer> list = Lists.newArrayList(1, 2, 3);
List<Integer> obj3 = Lists.transform(list, it -> it);
ArrayList<Integer> list = Lists.newArrayList(1, 2, 3);
List<Integer> obj3 = Lists.transform(list, it -> it);
List<Integer> obj4 = new ArrayList<>(obj3);
ArrayList<Integer> list = Lists.newArrayList(1, 2, 3, 4);
List<List<Integer>> obj3 = Lists.partition(list,2);
ArrayList<Integer> list = Lists.newArrayList(1, 2, 3, 4);
List<List<Integer>> lists = Lists.partition(list, 2)
.stream()
.map(Lists::newLinkedList)
.collect(Collectors.toList());
五
总结
往期回顾
文 / 羊羽
关注得物技术,每周一、三、五更新技术干货
要是觉得文章对你有帮助的话,欢迎评论转发点赞~
未经得物技术许可严禁转载,否则依法追究法律责任。
“
扫码添加小助手微信
如有任何疑问,或想要了解更多技术资讯,请添加小助手微信:
线下活动推荐