web-dev-qa-db-fra.com

Impossible de trouver un désérialiseur de clé (carte) pour le type [type simple, classe com.comcast.ivr.core.domain.AutoHandlingSlotKey]

J'ai un objet de domaine qui a une carte:

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

Lorsque je sérialise l'objet, j'obtiens ceci:

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

La clé de cette carte est un objet personnalisé:

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

Donc, je ne sais pas comment corriger ce problème que je continue à obtenir lorsque je désérialise l'objet:

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

Quelqu'un peut-il m'aider à comprendre comment corriger ce problème si je PAS ai accès à l'objet de domaine à modifier?

39
Mick Knutson

Par défaut, Jackson essaie de sérialiser Java Cartes en tant qu'objets JSON (paires clé/valeur), donc l'objet clé de carte doit être en quelque sorte sérialisé en chaîne; et il doit y avoir une clé correspondante (et enregistrée) désérialiseur. La configuration par défaut ne prend en charge qu'un petit ensemble de types JDK (chaîne, nombres, énumération). pour la même raison)

Deux façons évidentes de résoudre ce problème sont les suivantes:

  • Implémenter et enregistrer un "désérialiseur de clés"
  • Implémentez et enregistrez un désérialiseur personnalisé pour Maps.

Dans votre cas, il est probablement plus facile de faire le premier. Vous pouvez également implémenter un sérialiseur de clés personnalisé pour vous assurer que les clés sont sérialisées au format approprié.

La façon la plus simple d'enregistrer les sérialiseurs et désérialiseurs est de interface de module qui a été ajouté dans Jackson 1.7 (et étendu en 1.8 pour prendre en charge les sérialiseurs/désérialiseurs clés).

22
StaxMan

Cela a été demandé il y a longtemps et c'est le premier résultat google lors de la recherche de l'erreur, mais la réponse acceptée n'a pas de code et peut être déroutante pour un débutant jackson (moi). J'ai finalement trouvé cette réponse qui a aidé.

Ainsi, comme indiqué dans la réponse acceptée, la mise en œuvre et l'enregistrement d'un "désérialiseur de clés" est la voie à suivre. Vous pouvez faire ça comme ça.

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

Et pour la classe, il vous suffit de:

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

C'est ça! Pas d'annotation sur les classes, pas de désérialiseur personnalisé pour les cartes, etc.

25
estebanrv