• dubbo 序列化 问题 属性值 丢失 ArrayList 解决


    参考文章:http://blog.csdn.net/wanyanxgf/article/details/6944733

                      http://tianya23.blog.51cto.com/1081650/582256/

    这里重点说下解决办法:

    由于dubbo采用的序列化和反序列化方案为hessian,但是 hessian 对ArrayList 采用CollectionSerializer类进行 序列化处理,这里 实际代码只会对 ArrayList第一层属性进行处理。

    项目中使用PageList 封装类 继承了 ArrayList,并且里面有负责 java对象 PageTools,故 无法转换,属性丢失。

    public class PageList<E> extends ArrayList<E> {
        private static final long serialVersionUID = 6110720806295292900L;
        private PagingTools pagingTools;
    
        public PageList() {
            this.pagingTools = new PagingTools();
        }
    
        public PageList(Collection<E> c) {
            this(c, (PagingTools)null);
        }
    
        public PageList(Collection<E> c, PagingTools pageTools) {
            super(c);
            this.pagingTools = pageTools == null?new PagingTools():pageTools;
        }
    
        public PagingTools getPageTools() {
            return this.pagingTools;
        }
    
        public void setPageTools(PagingTools pageTools) {
            if(pageTools != null) {
                this.pagingTools = pageTools;
            }
    
        }
    }
    

      

    解决方法: 使用其他 序列化方案  ,这里试了 json ,结果一样。 最终没办法,使用了java原生的序列化。

    具体操作:  在 dubbo服务端和客户端 配置 序列化方案

    <dubbo:protocol serialization="java"/>

    h1. 现象

    为一个dubbbo接口新增了一个方法:

    1. {code}  
    2. DomainObject<String> testSer();  
    3.   
    4.   
    5. 实现:  
    6. @Override  
    7.     public DomainObject<String> testSer() {  
    8.         DomainObject<String> result = new DomainObject<String>();  
    9.         result.setAge(10);  
    10.         result.setName("test");  
    11.         result.add("DomainObject1");  
    12.         return result;  
    13.     }  
    14. {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.   
    10.   
    11.     Serializer serializer;  
    12.     ##查找对应的serializer  
    13.     serializer = findSerializerFactory().getSerializer(object.getClass());  
    14.     ##序列化  
    15.     serializer.writeObject(object, this);  
    16.   }  
    17. {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.   
    10.   
    11.       out.writeObject(value);  
    12.     }  
    13.     ...  
    14.   }  
    15. {code}  

    所以,属性丢失。

  • 相关阅读:
    学号20145220《信息安全系统设计基础》第10周学习总结
    补发周四的博客。对之前的知识复习了一遍,因为要闭卷考试。
    jsp中文乱码
    redis做成windows服务
    poi导出excel打开文件时部分内容有问题
    mysql删除数据表时:Cannot delete or update a parent row: a foreign key constraint fails
    Oracle使用foreach批量操作数据
    Oracle数据库clob类型转String类型
    MAVEN配置多个仓库
    idea中maven项目明明有jar包还是爆红
  • 原文地址:https://www.cnblogs.com/hutuchong/p/7170954.html
Copyright © 2020-2023  润新知