I'm attempting to use Jackson to serialize and deserialize a map containing arbitrary objects. According to the docs I've read I should be able to use enableDefaultTyping()
to tell Jackson to store the info I need in serialization, and have written the following simple test:
@Test
public void testObjectMap()
{
final ObjectMapper mapper = new ObjectMapper().enableDefaultTyping();
final Map<String, Object> map = Maps.newHashMap();
map.put("test1", new Date());
map.put("test2", new InetSocketAddress(10));
try
{
final String ser = mapper.writeValueAsString(map);
System.err.println(ser);
final Map<String, Object> deser = this.mapper.readValue(ser, new TypeReference<Map<String, Object>>(){});
assertTrue(deser.get("test1") instanceof Date);
assertTrue(deser.get("test2") instanceof InetSocketAddress);
}
catch (final IOException e)
{
fail("Failed", e);
}
}
The serialization looks okay, in that the System.err.println(ser)
line in the above code produces the output:
{"test1":["java.util.Date",1408312196267],"test2":["java.net.InetSocketAddress","0.0.0.0:10"]}
But the deserialization attempt fails with the following error:
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Unexpected token (START_OBJECT), expected START_ARRAY: need JSON Array to contain As.WRAPPER_ARRAY type information for class java.util.Map
at [Source: {"test1":["java.util.Date",1408312196267],"test2":["java.net.InetSocketAddress","0.0.0.0:10"]}; line: 1, column: 1]
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)
at com.fasterxml.jackson.databind.DeserializationContext.wrongTokenException(DeserializationContext.java:841)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._locateTypeId(AsArrayTypeDeserializer.java:122)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer._deserialize(AsArrayTypeDeserializer.java:93)
at com.fasterxml.jackson.databind.jsontype.impl.AsArrayTypeDeserializer.deserializeTypedFromObject(AsArrayTypeDeserializer.java:58)
at com.fasterxml.jackson.databind.deser.std.MapDeserializer.deserializeWithType(MapDeserializer.java:342)
at com.fasterxml.jackson.databind.deser.impl.TypeWrappedDeserializer.deserialize(TypeWrappedDeserializer.java:41)
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:3051)
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2153)
at test.JacksonModuleTest.testObjectMap(JacksonModuleTest.java:119)
I'm unsure what Jackson is complaining about here; I can only assume that it expects the map itself to have some sort of typing but I'm unsure how to provide this.
I'm using jackson 2.4.0
You should take a look at How to convert a JSON string to a Map<String, String> with Jackson JSON where there is the following code :
JsonFactory factory = new JsonFactory();
ObjectMapper mapper = new ObjectMapper(factory);
TypeReference<HashMap<String,Object>> typeRef
= new TypeReference<HashMap<String,Object>>() {};
HashMap<String,Object> o = mapper.readValue(inputFile, typeRef);
Maybe the fact that you used the abstract class Map
instead of a concrete implementation (HashMap
in the above code) explains that Jackson has some difficulties when trying to fill this structure...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With