![](/img/trans.png)
[英]Deserialize a Jackson serialized object to Map<String, Object>?
[英]Jackson: Deserialize to a Map<String, Object> with correct type for each value
我有一个如下所示的课程
public class MyClass {
private String val1;
private String val2;
private Map<String,Object> context;
// Appropriate accessors removed for brevity.
...
}
我希望能够与杰克逊一起往返于JSON并返回。 我可以序列化上面的对象并收到以下输出:
{
"val1": "foo",
"val2": "bar",
"context": {
"key1": "enumValue1",
"key2": "stringValue1",
"key3": 3.0
}
}
我遇到的问题是,由于序列化映射中的值没有任何类型信息,因此它们不会正确反序列化。 例如,在上面的示例中,enumValue1应该反序列化为枚举值,而是反序列化为String。 我已经看到了基于各种类型的基于什么类型的示例,但在我的场景中,我不知道类型是什么(它们将是用户生成的对象,我不会事先知道)所以我需要成为能够使用键值对序列化类型信息。 我怎么能和杰克逊一起完成这个?
为了记录,我使用Jackson版本2.4.2。 我用来测试往返的代码如下:
@Test
@SuppressWarnings("unchecked")
public void testJsonSerialization() throws Exception {
// Get test object to serialize
T serializationValue = getSerializationValue();
// Serialize test object
String json = mapper.writeValueAsString(serializationValue);
// Test that object was serialized as expected
assertJson(json);
// Deserialize to complete round trip
T roundTrip = (T) mapper.readValue(json, serializationValue.getClass());
// Validate that the deserialized object matches the original one
assertObject(roundTrip);
}
由于这是一个基于Spring的项目,因此映射器的创建方式如下:
@Configuration
public static class SerializationConfiguration {
@Bean
public ObjectMapper mapper() {
Map<Class<?>, Class<?>> mixins = new HashMap<Class<?>, Class<?>>();
// Add unrelated MixIns
..
return new Jackson2ObjectMapperBuilder()
.featuresToDisable(SerializationFeature.WRITE_DATE_KEYS_AS_TIMESTAMPS)
.dateFormat(new ISO8601DateFormatWithMilliSeconds())
.mixIns(mixins)
.build();
}
}
我认为实现你想要的最简单的方法是使用:
ObjectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
这将在序列化的json中添加类型信息。
在这里你是一个运行的例子,你将需要适应Spring:
public class Main {
public enum MyEnum {
enumValue1
}
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
MyClass obj = new MyClass();
obj.setContext(new HashMap<String, Object>());
obj.setVal1("foo");
obj.setVal2("var");
obj.getContext().put("key1", "stringValue1");
obj.getContext().put("key2", MyEnum.enumValue1);
obj.getContext().put("key3", 3.0);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
System.out.println(json);
MyClass readValue = mapper.readValue(json, MyClass.class);
//Check the enum value was correctly deserialized
Assert.assertEquals(readValue.getContext().get("key2"), MyEnum.enumValue1);
}
}
该对象将被序列化为类似于:
[ "so_27871226.MyClass", {
"val1" : "foo",
"val2" : "var",
"context" : [ "java.util.HashMap", {
"key3" : 3.0,
"key2" : [ "so_27871226.Main$MyEnum", "enumValue1" ],
"key1" : "stringValue1"
} ]
} ]
并且将被正确地反序列化,并且断言将通过。
顺便提一下,有更多的方法,请查看https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization了解更多信息。
我希望它会有所帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.