web-dev-qa-db-fra.com

Représentation JSON de la carte avec clé complexe

Je souhaite sérialiser en JSON la structure de données suivante (Java):

class Machine {
  String name;
  Map<PartDescriptor, Part> parts;
}

class PartDescriptor {
  String group;
  String id;

  hashCode()
  equals()
}

class Part {
  String group;
  String id;
  String description;
  String compat;
  ...
  ...
}

Quelle serait la représentation JSON d'une Machine?

Aussi ( facultatif ), pointez-moi vers un sérialiseur/désérialiseur JSON vers Java qui prendra en charge votre représentation.

12
Op De Cirkel

Je ferais quelque chose comme:

{
  "name": "machine name",
  "parts": [
     { "group": "part group", "id": "part id", "description": "...", ... },
     { "group": "part group", "id": "part id", "description": "...", ... },
     // ...
  ]
}

Si "l'id" de chaque partie est unique, la propriété "parts" peut être un objet au lieu d'un tableau, "id" de chaque partie servant de clé.

{
  "name": "machine name",
  "parts": {
     "1st part id": { "group": "part group", "description": "...", ... },
     "2nd part id": { "group": "part group", "description": "...", ... },
     // ...
  }
}
9
Pointy

Vous n'avez pas besoin d'annotations ni de sérialiseurs personnalisés. En supposant que vous ayez déjà des getters pour tous les champs dans Part et Machine, tout ce qui manque est une toString() sur PartDescriptor. Si, pour une raison quelconque, vous n’avez pas de fonctions d’acquisition, vous devez annoter les champs d’intérêt avec @JsonProperty pour que Jackson sache quels champs inclure dans la sortie sérialisée. Cependant, il est préférable (et plus facile) de créer simplement des accesseurs.

La toString() sur PartDescriptor devrait renvoyer la clé que vous souhaitez utiliser dans votre mappage. Comme le suggère une autre réponse, vous pouvez simplement concaténer les champs pertinents:

@Override
public String toString() {
    return group + "|" + id;
}

Comme par magie, vous obtiendrez ce formulaire lorsque vous tenterez de sérialiser une Machine avec le ObjectMapper de Jackson:

{
  "name" : "Toaster",
  "parts" : {
    "Electrical|Descriptor1" : {
      "group" : "Electrical",
      "id" : "Part1",
      "description" : "Heating Element",
      "compat" : "B293"
    },
    "Exterior|Descriptor2" : {
      "group" : "Exterior",
      "id" : "Part2",
      "description" : "Lever",
      "compat" : "18A"
    }
  }
}
8
quietmint

Je ferais ça. La clé parts de l'objet de niveau supérieur serait une JSONArray de JSONObject qui aurait key 's et value' s. La key serait un objet qui est votre PartDescriptor et la value serait votre Part.

{
    "name":"theName",
    "parts":[
        {
            "key":{
                       "group":"theGroup",
                       "id":"theId"
                  },
            "value":{
                       "group":"theGroup",
                       "id":"theId",
                       "description":"theDescription",
                       "compat":"theCompat",
                       ...
                    }
        },
        ...
    ]
}
2

En supposant que groupe + id donne une combinaison unique, et que ":" est un séparateur autorisé:

{  
   "name": "machine name",
   "parts": { 
               "somegroup:01465": {
                                    "group":"somegroup",
                                    "id": "01465",
                                    ...
                                  },
               "othergroup:32409": {
                                     "group":"othergroup",
                                     "id": "32409",
                                     ...
                                   }

            }
}
1
Phil H