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}  

所以,屬性丟失。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM