我有一个班级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 Handling在jsonString
中嵌入类型信息,似乎确实有一种方法让映射器知道序列化前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
类型值的地图中?