2013-07-08 114 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