2011-10-24 80 views
0

我有此JSON例如:XSTREAM JSON - 如何處理空值

{ 
    "rows": [ 
     { 
      "anaid": "1", 
      "anaint": "123", 
      "anastring": "-" 
     }, 
     { 
      "anaid": "2", 
      "anaint": "-", 
      "anastring": "Hello World" 
     }, 
     { 
      "anaid": "3", 
      "anaint": "-", 
      "anastring": "-" 
     } 
    ] 
} 

凡在我的課測試是:

  • INT阿奈德
  • INT anaint
  • 字符串anastring

我的java代碼:

XStream xstream = new XStream(new JettisonMappedXmlDriver()); 
xstream.alias("rows", Test.class); 
ArrayList<Test> product = (ArrayList<Test>) xstream.fromXML(json); 

所以字符「 - 」是我的json的空值。我無法更改代碼來創建json,但我會處理「 - 」null值以正確使用我的xStream解析器。

回答

0

使用自定義轉換器。教程here

+0

我已閱讀,但我不明白我該怎麼辦... – CeccoCQ

0

根據XStream的文檔和郵件列表,空值不包含在編組輸出中 - 也許是作爲一種約定。

A discussion幫我弄清楚瞭如何顯示它們。簡而言之,訣竅是Varun所說的:一種自定義轉換器,用於擴展默認的ReflectionConverter。這個想法是停止忽略空值事件並將它們寫入輸出。

下面是關於如何爲我工作的詳細說明。不幸的是,我不能分發最終的解決方案;我希望以下解鎖許多,甚至導致在主樹中的集成。

配方

這是我的溶液的主旨的基礎上,[1]及XStream 1.4.2:

  1. 擴展com.thoughtworks.xstream.converters.reflection.ReflectionConverter類。
  2. 重寫doMarshal/3方法。原始方法忽略空事件,因此什麼都不寫。新方法應該只是採取這些事件並寫出想要的東西(一個空節點,一個自閉節點)。
  3. 重寫writeField/5方法來寫入空值節點。寫什麼取決於想要什麼,應該委託給作者對象。
  4. 擴展com.thoughtworks.xstream.io.ExtendedHierarchicalStreamWritercom.thoughtworks.xstream.io.ExtendedHierarchicalStreamWriterHelper類以提供自定義書寫器。需要一個方法來記錄空值節點。
  5. 註冊轉換器,具有非常低的優先級(因爲反射是基本的,並將接管其他轉換器)。上的辦法

    例如

的更多細節,可以延伸設置有XStream的作家和實現額外的接口:

// Context of "MyReflectionConverter"'s doMarshal method. 
void writeField(...) 
    if (newObj == null) { 
     NullExtendedHierarchicalStreamWriterHelper.emptyNode(
         writer.underlyingWriter(), 
         aliasName != null ? aliasName: 
          mapper.serializedMember(source.getClass(), fieldName), 
         fieldType); 
    } 
    else { // Rest of the original writeField method 
    } 
} 

的接口是這裏NullExtendedHierarchicalStreamWriter其中增加了一個emptyNode/2方法到ExtendedHierarchicalStreamWriter。此方法將空值作爲自關閉節點寫入(例如,對於XML <int value="num"/>,意思是num是空整數)。上面的代碼片段使用助手NullExtendedHierarchicalStreamWriterHelper得到了這位作者的一個實例,它本身就是ExtendedHierarchicalStreamWriterHelper的簡單擴展。請注意,作爲傳遞給幫助器的writer是writer.underlyingWriter(),因爲編寫器被封裝並且封裝器不實現接口的空擴展---這意味着我的解決方案仍然是黑客,直到完成更深層次的整合。所述轉換器的

登記典型的做法是這樣的:

serializer = new XStream(new MyStreamDriver()); 

MyReflectionConverter reflectionConverter = new 
     MyReflectionConverter(serializer.getMapper(), 
           serializer.getReflectionProvider()); 
serializer.registerConverter(reflectionConverter, XStream.PRIORITY_VERY_LOW); 

Here是上述定製反射變換器的一個diff,對原來的代碼。請考慮這是一個不屬於主樹的擴展,它比原始代碼要少得多。迄今爲止它通過了測試套件的情況。

0

對我來說,最簡單的方式是獲得源代碼,複製ReflexionConverted類的方法public void元帥(原對象,最終HierarchicalStreamWriter作家,最終MarshallingContext上下文)...

您有:

reflectionProvider.visitSerializableFields(source, new ReflectionProvider.Visitor() { 
    public void visit(String fieldName, Class fieldType, Class definedIn, Object newObj) { 
     if (newObj != null) { 
      ... 
      complete the else method with your code...for example: 

     } else { 
      Object obj = new String(""); 

      writeField(fieldName, fieldType, definedIn, obj); 
      seenFields.add(fieldName); 

     } 
    } 
}