web-dev-qa-db-fra.com

Comment dérouler et sérialiser une carte Java en Java en utilisant Jackson?

J'ai un haricot comme ça

class Foo {
    private Map<String, Data> dataMap;
    private String fooFieldOne;
    private String fooFieldTwo;
}

class Data {
    private fieldOne;
    private fieldTwo;
}

Je veux sérialiser comme Json comme ça

{
    "key1": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    },
    "key2": {
        "fieldOne": "some other value",
        "fieldTwo": "some other value"
    },
    "fooFieldOne":"valueone", 
    "fooFieldTwo":"valuetwo" 
}

Mais j'obtiens un résultat comme

{
    "dataMap": {
        "key1": {
            "fieldOne": "some value",
            "fieldTwo": "some value"
        },
        "key2": {
            "fieldOne": "some other value",
            "fieldTwo": "some other value"
        }
    },
    "fooFieldOne":"valueone", 
    "fooFieldTwo":"valuetwo" 
}

Comment ignorer la couche dataMap dans le JSON ci-dessus? J'utilise la bibliothèque Java Jackson pour cela. 

Le code que j'ai essayé est

ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString(myFOOObject)
14
Suren Raju

Vous pouvez créer un getter pour dataMap et sérialiser le dataMap au lieu de l'instance entière Foo.

mapper.writeValueAsString(myFOOObject.getDataMap());

Une autre méthode utilise l'annotation @JsonUnwrapped. Cette annotation est disponible dans Jackson 1.9+.

http://jackson.codehaus.org/1.9.9/javadoc/org/codehaus/jackson/annotate/JsonUnwrapped.html

L’inconvénient de l’utilisation de cette annotation est l’incapacité à utiliser les cartes, comme indiqué dans le réponse à votre autre question

11
Bart

Vous obtenez

{ "dataMap": ... } 

parce que Foo contient un champ appelé dataMap. Ici, le nom du champ ne peut pas être ignoré car il va créer conflits si Foo avait plusieurs cartes, quelque chose comme

class Foo {
private Map<String, Data> dataMap1;
private Map<String, Data> dataMap2;
}

maintenant sans avoir le fieldName: en JSON, le JSON ne sait pas comment désérialiser quand il obtient du JSON comme

{
    //belongs to dataMap1
    "key1": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    },
    "key2": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    },
    //belongs to dataMap2
    "key3": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    },
    "key4": {
        "fieldOne": "some other value",
        "fieldTwo": "some other value"
    }
}

Maintenant, avoir le nom de champ rend très clair en désérialisant

{
    "dataMap1" : {
    "key1": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    },
    "key2": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    }
    },
    "dataMap2" : {
    "key3": {
        "fieldOne": "some value",
        "fieldTwo": "some value"
    },
    "key4": {
        "fieldOne": "some other value",
        "fieldTwo": "some other value"
    }
  }
}

Ayant dit cela

Comment ignorer la couche dataMap dans le json?

Vous pouvez simplement sérialiser la carte

ObjectMapper mapper = new ObjectMapper();
mapper.writeValueAsString(myFOOObject.getDataMap());
2
sanbhat

J'ai trouvé la réponse - en utilisant l'annotation @JsonAnyGetter avec getter pour la carte. Pour éviter les conflits lors de la désérialisation, utilisez l'annotation @JsonAnySetter avec setter pour cette carte.

1
T.Loner

Dans la carte, il y a deux objets String et Data. JSON convertit les objets Java en une paire valeur-clé JSON, mais si vous avez déjà une carte contenant une paire valeur-clé et convertissez cette carte en document JSON, cette clé est également convertie en paire clé JSON et la valeur Carte a également un objet qui convertissent en paire clé-valeur. 

0