java - Flex JSON 无法正确序列化/反序列化 LinkedHashMap

标签 java json flexjson

我尝试序列化和反序列化 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}

最佳答案

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

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

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

关于java - Flex JSON 无法正确序列化/反序列化 LinkedHashMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17519228/

相关文章:

c# - ASP Core Minimal API - 如何使用 System.Text.Json 发送不带尾随零的小数?

java - 如何避免 "flexjson.JSONSerializer"将日期时间对象转换为时间戳?我想要像 yyyy/MM/dd hh :mm:ss 这样的字符串

java - Runnable 不再在 Service 中运行以定期从 URL 检索

java - Spring - SaltSource 为空

json - httr 库中的 POST 方法与 R 中的特定 header

android - Android 4.4.4 上的 FlexJson ClassNotFound 异常

java - 信息丰富的 Java 游戏开发教程?

java - Java 中的 Opencv Android 模板匹配

ios - 在 Objective-C 中解析 JSON 的最漂亮方法?