如何将带有类型信息的json反序列化为Map <string,object =“”>?

时间:2017-07-15 18:13:08

标签: java serialization jackson polymorphism deserialization

我有一个班级SomeClass

public class SomeClass {
    public String someString = "SOME-STRING-VALUE";

    public Date someDate = new Date();
}

我的目标是创建一个Map<String, Object>,其中包含SomeClass的成员名称作为键,其值作为给定SomeClass实例的地图中的值

为此,我使用Jackson如下:

SomeClass someObject = new SomeClass();

ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(someObject);    // serialize object
System.out.println(jsonString);    // {"someString":"SOME-STRING-VALUE","someDate":1500138786720}

Map<String, Object> objectMap = mapper.readValue(jsonString, Map.class);    // deserialize back to Map instead of SomeClass
objectMap.forEach((k, v) -> System.out.println(k + " : " + v + " : " + v.getClass()));
// This prints:
// someString : SOME-STRING-VALUE : class java.lang.String
// someDate : 1500138786720 : class java.lang.Long

所以我使用object-mapper将对象序列化为jsonString,然后创建所需的地图,我将jsonString反序列化为Map

这里的问题是,Date字段被序列化为原始长值,而反序列化则将其反序列化为Long而不是Date,因为我正在反序列化它到Object。如果我将反序列化返回到SomeClass,则Long值将转换为相关的Date值。但就我的情况而言,在反序列化时,mapper在反序列化之前并不知道someDate的实际类型是什么,因此someDate被反序列化为Long本身在objectMap

通过使用Jackson Polymorphic Type HandlingjsonString中嵌入类型信息,似乎确实有一种方法让映射器知道序列化前jsonString中给定字段的类型是什么。为此,我在使用:

编写jsonString之前启用了默认输入

mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);

我现在获得的jsonString是:

["some.package.name.here.SomeClass",{"someString":"SOME-STRING-VALUE","someDate":["java.util.Date",1500140185993]}]

因此jsonString现在包含someDate字段的类型。但是我很难将此jsonString内容的类型信息回读给objectMap。我得到了例外:

  

java.lang.IllegalArgumentException:class some.package.name.here.SomeClass   不是[地图类型的子类型; class java.util.Map,[simple type,class   java.lang.Object] - &gt; [simple type,class java.lang.Object]]

我是否需要将行Map<String, Object> objectMap = mapper.readValue(jsonString, Map.class);更改为其他内容,以使mapper知道它要读取的字符串不是普通字符串,而是嵌入了类型信息的字符串。难道映射器不应该已经知道这一点,因为我们用来读取jsonString的映射器对象是写它的映射器对象吗?

我发现的所有示例都遵循继承层次结构示例,其中读取时它们只会传递BaseClass,但我无法弄清楚我应该为我的案例做些什么。

如何将someDate字段从Date转换回Long,同时将其放入具有Object类型值的地图中?

0 个答案:

没有答案