【问题标题】:Flex JSON unable to properly serialize/deserialize LinkedHashMapFlex JSON 无法正确序列化/反序列化 LinkedHashMap
【发布时间】:2013-07-08 04:31:12
【问题描述】:

我尝试对 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 似乎对排序的 Map 有问题。我猜这是因为它无法像下面的示例那样放置“类”条目,例如。

"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}

【问题讨论】:

    标签: java json flexjson


    【解决方案1】:

    默认情况下,没有输入信息的对象被解释为 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。

    【讨论】:

    • 谢谢,但当时地图排序已经改变。在顶部查看我编辑的评论。
    • 那是因为你实际上并没有在你的 ObjectFactory 中做任何事情。您写出的是 flexjson 在将 HashMap 绑定到 ObjectFactory 创建的对象之前解析的 HashMap(没有顺序)。您必须通过在 ObjectFactory 中实例化一个并将值移动到其中来将其转换为 LinkedHashMap。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-28
    • 2019-05-02
    相关资源
    最近更新 更多