Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can not find a (Map) Key deserializer for type [simple type, class ...]

I have a domain object that has a Map:

private Map<AutoHandlingSlotKey, LinkedHashSet<AutoFunction>> autoHandling; 

When I serialize the object, I get this:

"autoHandling" : [ "java.util.HashMap", { } ], 

This Map's key is a custom Object:

public class AutoHandlingSlotKey implements Serializable {     private FunctionalArea slot; // ENUM     private String returnView;   // ENUM 

So, I am not sure how to correct this exception I keep getting when I deserialize the object:

org.codehaus.jackson.map.JsonMappingException: Can not find a (Map) Key deserializer for type [simple type, class com.comcast.ivr.core.domain.AutoHandlingSlotKey] 

How to correct this issue? I do not have access to the domain object to modify.

like image 225
Mick Knutson Avatar asked Jun 16 '11 11:06

Mick Knutson


2 Answers

This was asked a long time ago, and is the first google result when looking up the error, but the accepted answer has no code and might be confusing for a jackson beginner (me). I eventually found this answer that helped.

So, as stated in accepted answer, Implementing and register a "key deserializer" is the way to go. You can do this like this.

SimpleModule simpleModule = new SimpleModule(); simpleModule.addKeyDeserializer(YourClass.class, new YourClassKeyDeserializer()); objectMapper.registerModule(simpleModule); 

And for the class, all you have to do is:

class YourClassKeyDeserializer extends KeyDeserializer {     @Override     public Object deserializeKey(final String key, final DeserializationContext ctxt ) throws IOException, JsonProcessingException     {         return null; // replace null with your logic     } } 

That's it! No annotation on classes, not custom deserializer for maps, etc.

like image 91
estebanrv Avatar answered Sep 27 '22 19:09

estebanrv


By default, Jackson tries to serialize Java Maps as JSON Objects (key/value pairs), so Map key object must be somehow serialized as a String; and there must be matching (and registered) key deserializer. Default configuration only supports a small set of JDK types (String, numbers, enum). So mapper has no idea as to how to take a String and create AutoHandlingSlotKey out of it. (in fact I am surprised that serializer did not fail for same reason)

Two obvious ways to solve this are:

  • Implement and register a "key deserializer"
  • Implement and register a custom deserializer for Maps.

In your case it is probably easier to do former. You may also want to implement custom key serializer, to ensure keys are serializer in proper format.

The easiest way to register serializers and deserializers is by Module interface that was added in Jackson 1.7 (and extended in 1.8 to support key serializers/deserializers).

like image 32
StaxMan Avatar answered Sep 27 '22 20:09

StaxMan