2

我尝试对 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);

这次我得到了结果,但 Map 是无序的(我认为是因为它现在使用的是 HashMap)。此外,BigDecimal 值不像原始格式那样显示。

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

FlexJSON 似乎对排序的地图有问题。我想这是因为它无法像下面的示例那样放置“类”条目,例如。

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

或者也许还有另一种方法可以做到这一点。有人可以帮忙吗?谢谢


按照chubbsondubs的建议引入ObjectFactory后:

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, 4=flexjson.JsonNumber@104fc23}
4

1 回答 1

2

默认情况下,没有输入信息的对象被解释为 HashMap,文档中对此进行了解释。它不使用 HashMap 的情况是,它是否可以从嵌入的类属性(有效,但在网络上不安全)、通过对象路径指定的类型或反序列化为它可以解释类型的类型化对象。

因此,像标准集合这样的类,Flexjson 无法从 Collection/Map 类中推断出包含的类型,因为它们是运行时的简单对象引用。数字是 JSON 不指定任何类型信息的另一个领域。当我们将一个数字映射到 Java 时,它可能是以下几种类型之一:byte、short、int、long、BigInteger、float、double、BigDecimal。如果没有指定输入信息,Flexjson 必须进行调用。默认情况下,如果它是一个小数,它使用 double,如果它是一个整数,它使用 long。在您的情况下,它是双倍的,这就是它以指数格式显示的原因。

您必须指定所需的类型。通过使用类型化对象、在对象路径上配置类型或创建自定义 ObjectFactory。我认为 ObjectFactory 是您唯一的选择,除非您可以创建类型化对象。原因是因为 Map 中的值类型不同。有些条目是字符串,而另一个是 BigDecimal。因此,您必须有一个特殊的 ObjectFactory,它知道实例化 LinkedHashMap 并将所有键从源复制到目标,如果源的值为 JsonNumber,则将它们转换为 BigDecimal。

于 2013-07-08T20:47:37.147 回答