Reputation:
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
Upvotes: 4
Views: 9797
Reputation: 11992
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...
Upvotes: 3