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}
所以,属性丢失。