2013-07-08 148 views
2

我試圖序列和deseriliaze LinkedHashMap的數據如下:Flex的JSON不能正確序列化/反序列化的LinkedHashMap

LinkedHashMap<String, Object> o = new LinkedHashMap<String, Object>(); 
o.put("1", "a"); 
o.put("2", "b"); 
o.put("3", "c"); 
o.put("4", new BigDecimal("9999999999999999999999.00999999999999999999999")); 

String serialize = new JSONSerializer().deepSerialize(o); 
System.out.println("serialize" + serialize); 

LinkedHashMap deserialize = new JSONDeserializer<LinkedHashMap>().deserialize(serialize, LinkedHashMap.class); 
System.out.println("deserialize:" + deserialize); 

,我也得到ClassCastException異常:

serialize{"1":"a","2":"b","3":"c","4":9999999999999999999999.00999999999999999999999} 
Exception in thread "main" java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.LinkedHashMap 
    at com.JSONUtil.main(JSONUtil.java:161) 

所以我反序列化時,試圖略微不同的方法如下所示:

HashMap deserialize = new JSONDeserializer<HashMap>().deserialize(serialize, HashMap.class); 
System.out.println("deserialize:" + deserialize); 

這次我得到結果,但地圖是無序的(我認爲是因爲它現在使用HashMap)。另外,BigDecimal值不像原始格式那樣顯示。

deserialize:{3=c, 2=b, 1=a, 4=1.0E22} 

看來FlexJSON對排序後的Map有問題。我想這是因爲它沒有辦法像下面的例子那樣放入'class'條目,例如。

"class":"ch.qos.logback.classic.Logger","debugEnabled":true,"errorEnabled":true,"infoEnabled":true} 

或者也許有另一種方式來做到這一點。任何人都可以幫忙嗎? 謝謝


引入了ObjectFactory後的建議由chubbsondubs:

LinkedHashMap deserialize = new JSONDeserializer<LinkedHashMap>() 
.use(LinkedHashMap.class, new ObjectFactory() { 
public Object instantiate(ObjectBinder context, Object value, Type targetType, Class targetClass) { 
    System.out.println("mymap:"value); 
} 
}).deserialize(serialize, LinkedHashMap.class); 

值對象有HashMap的類型,它打印:

mymap:{3=c, 2=b, 1=a, [email protected]} 

回答

2

默認情況下不輸入信息是一個對象解釋爲在文檔中解釋的HashMap。它不會使用HashMap的時間是,它可以根據嵌入類屬性(它可以工作,但對網絡不安全),按對象路徑指定的類型,或者如果要反序列化爲一個可以解釋類型的類型化對象。

因此類似標準集合Flexjson無法從集合/映射類中推斷包含的類型,因爲它們在運行時是簡單的對象引用。數字是JSON未指定任何類型信息的另一個區域。當我們將一個數字映射到Java時,它可能是幾種變體之一:byte,short,int,long,BigInteger,float,double,BigDecimal。如果沒有指定輸入信息,Flexjson必須撥打電話。默認情況下,如果它是一個小數,則使用double;如果是整數,則使用long。在你的情況下,它是雙重的,這就是爲什麼它以指數格式顯示。

你必須指定你想要的類型。通過使用類型化對象,在對象路徑上配置類型或創建自定義ObjectFactory。除非你可以創建類型化對象,否則我認爲ObjectFactory是唯一的選擇。原因在於您的地圖中的值因類型而異。有些條目是字符串,另一個是BigDecimal。所以你必須有一個特殊的ObjectFactory,它知道實例化一個LinkedHashMap,並將所有的鍵從源複製到目標,如果源的值是JsonNumber,則將它們轉換爲BigDecimal。

+0

謝謝,但當時地圖排序已經改變。在頂部看到我編輯的評論。 –

+0

這是因爲你實際上沒有在你的ObjectFactory中做任何事情。你寫出的是Flexjson在將HashMap綁定到ObjectFactory創建的對象之前解析的HashMap(沒有順序)。你必須通過在ObjectFactory中實例化一個LinkedHashMap並將其移入它來將它翻譯成LinkedHashMap。 – chubbsondubs