h1. 现象
为一个dubbbo接口新增了一个方法:
- {code}
- DomainObject<String> testSer();
- 实现:
- @Override
- public DomainObject<String> testSer() {
- DomainObject<String> result = new DomainObject<String>();
- result.setAge(10);
- result.setName("test");
- result.add("DomainObject1");
- return result;
- }
- {code}
返回值定义如下:
- {code}
- public class DomainObject<E> extends ArrayList<E> {
- private static final long serialVersionUID = -7393642276493435828L;
- private String name;
- private int age;
- }
- {code}
远程调用:
- {code}
- DomainObject<String> result = voucherInfoQueryService.testSer();
- System.out.println(result.getAge());
- System.out.println(result.getName());
- System.out.println(result.get(0));
- {code}
输出结果:丢失了age和name两个属性的值,而 list内部的值还是存在的
- {code}
- 0
- null
- DomainObject1
- {code}
h1. 问题排查
h4. 使用java自带序列化执行序列化和反序列化, 不会出现属性丢失的问题,怀疑dubbo序列化有特殊处理
h4. dubbo 默认用的序列化协议是hessian2,查看代码
序列化时代码如下:
- {code}
- public void writeObject(Object object)
- throws IOException
- {
- if (object == null) {
- writeNull();
- return;
- }
- Serializer serializer;
- ##查找对应的serializer
- serializer = findSerializerFactory().getSerializer(object.getClass());
- ##序列化
- serializer.writeObject(object, this);
- }
- {code}
查找serializer:由代码可知,上面的DomainObject对应的serializer是CollectionSerializer
- {code}
- public Serializer getSerializer(Class cl)
- throws HessianProtocolException
- {
- ...
- else if (Collection.class.isAssignableFrom(cl)) {
- if (_collectionSerializer == null) {
- _collectionSerializer = new CollectionSerializer();
- ...
- }
- {code}
CollectionSerializer.writeObject
- {code}
- public void writeObject(Object obj, AbstractHessianOutput out)
- throws IOException
- {
- ...
- Iterator iter = list.iterator();
- while (iter.hasNext()) {
- Object value = iter.next();
- out.writeObject(value);
- }
- ...
- }
- {code}
所以,属性丢失。