转载

Dubbo序列化值丢失

h1. 现象

为一个dubbbo接口新增了一个方法:
  1. {code}
  2. DomainObject<String> testSer();
  3. 实现:
  4. @Override
  5.     public DomainObject<String> testSer() {
  6.         DomainObject<String> result = new DomainObject<String>();
  7.         result.setAge(10);
  8.         result.setName("test");
  9.         result.add("DomainObject1");
  10.         return result;
  11.     }
  12. {code}
返回值定义如下:
  1. {code}
  2. public class DomainObject<E> extends ArrayList<E> {
  3.     private static final long serialVersionUID = -7393642276493435828L;
  4.     private String name;
  5.     private int    age;
  6. }
  7. {code}
远程调用:
  1. {code}
  2. DomainObject<String> result = voucherInfoQueryService.testSer();
  3. System.out.println(result.getAge());
  4. System.out.println(result.getName());
  5. System.out.println(result.get(0));
  6. {code}
输出结果:丢失了age和name两个属性的值,而 list内部的值还是存在的
  1. {code}
  2. 0
  3. null
  4. DomainObject1
  5. {code}

h1. 问题排查

h4. 使用java自带序列化执行序列化和反序列化, 不会出现属性丢失的问题,怀疑dubbo序列化有特殊处理

h4. dubbo 默认用的序列化协议是hessian2,查看代码

序列化时代码如下:
  1. {code}
  2. public void writeObject(Object object)
  3.     throws IOException
  4.   {
  5.     if (object == null) {
  6.       writeNull();
  7.       return;
  8.     }
  9.     Serializer serializer;
  10.     ##查找对应的serializer
  11.     serializer = findSerializerFactory().getSerializer(object.getClass());
  12.     ##序列化
  13.     serializer.writeObject(object, this);
  14.   }
  15. {code}
查找serializer:由代码可知,上面的DomainObject对应的serializer是CollectionSerializer
  1. {code}
  2. public Serializer getSerializer(Class cl)
  3.     throws HessianProtocolException
  4.   {
  5.   ...
  6.    else if (Collection.class.isAssignableFrom(cl)) {
  7.       if (_collectionSerializer == null) {
  8.     _collectionSerializer = new CollectionSerializer();
  9.    ...
  10.       }
  11. {code}
CollectionSerializer.writeObject
  1. {code}
  2. public void writeObject(Object obj, AbstractHessianOutput out)
  3.     throws IOException
  4.   {
  5.     ...
  6.     Iterator iter = list.iterator();
  7.     while (iter.hasNext()) {
  8.       Object value = iter.next();
  9.       out.writeObject(value);
  10.     }
  11.     ...
  12.   }
  13. {code}
所以,属性丢失。
正文到此结束
Loading...