Search code examples
javajsonserializationjacksonjackson2

Jackson - serialization of Map<String, Object> implementation


I have following class:

public class Some implements Map<String, Object>{
    private Map<String, Object> innerMap;
    //implementation that can only set innerMap in constructor and cannot add or remove values
}

The problem is that I cannot deserialize this in jackson correctly. If I serialize without default typing, it is OK, since it is serialized as {"one":"two"} and deserialized correctly (I had to implement deserializer with

return new Some(jp.readValueAs(new TypeReference<HashMap<String,Object>>(){}));

When I use default typing turned on, this is serialized as

["com.class.Some",{"one":"two"}]

But deserialization is throwing

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.HashMap

Any thoughts?


Solution

  • This is what I needed - custom deserializer:

    public class SomeDeserializer extends JsonDeserializer<Some> {
    
        @Override
        public Object deserializeWithType(JsonParser jsonParser, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
            return typeDeserializer.deserializeTypedFromObject(jsonParser, ctxt);
        }
    
        @SuppressWarnings("unchecked")
        @Override
        public Some deserialize(JsonParser jp, DeserializationContext ctxt)
                throws IOException {
            JsonDeserializer<Object> deserializer = ctxt.findRootValueDeserializer(
                    ctxt.getTypeFactory().constructMapType(Map.class, String.class, Object.class));
    
            return new Some((Map) deserializer.deserialize(jp, ctxt, new HashMap<>()));
        }
    }