3 votes

Jackson Nested Object Deserialization into property (Désérialisation d'objets imbriqués dans une propriété)

Supposons que j'ai un objet json qui ressemble à :

  {
    id: 1,
    name: "john doe"
    spouse: 2
  }

et la classe dans laquelle je veux qu'il la désérialise :

class Person{

  private Long id;
  private String name;

  private Person spouse;

  //getters/setters
}

Existe-t-il un moyen de demander à Jackson d'étendre le champ d'application de la spouse: 2 dans un nouveau POJO Personne avec id=2 lors de la désérialisation du JSON ?

J'ai rencontré ce problème suite à la désérialisation de JSON en entités persistantes et j'aimerais pouvoir facilement persister les relations entre ces entités.

3voto

StaxMan Points 34626

Outre un désérialiseur complet, il existe un moyen plus simple : définir un POJO avec un seul constructeur int-arg comme suit :

class Person {
   int id;
   public Person(int id) {
     this.id = id;
   }
}

Cela fonctionne en fait, car Jackson essaiera de trouver un nombre limité de constructeurs spéciaux (des constructeurs publics à un seul argument qui prennent String, int, long, double ou boolean).

Vous pouvez éventuellement les dénoter avec @JsonCreator -- et si le constructeur n'est pas public, vous devez le faire, pour qu'il puisse être découvert. Mais pour les ctors publics, ce n'est pas nécessaire.

2voto

SingleShot Points 9258

Il est bien sûr impossible pour Jackson de déduire qu'un pays entièrement peuplé est en train de se développer. Person représentant le conjoint du numéro 2 . Vous devrez probablement enregistrer un désérialiseur personnalisé qui vérifie si l'entrée est un entier et, si c'est le cas, recherche le conjoint là où il est stocké. Je n'ai pas fait ce genre de choses pour les classes qui contiennent des références à elles-mêmes (par exemple, votre Person contient un Person ), je ne peux donc que vous donner des indications approximatives.

Je crois que cela ne fonctionne qu'avec la version Jackson 1.9 ou plus tard. Fondamentalement, vous pouvez enregistrer un module avec le mappeur d'objets qui indique à Jackson d'utiliser un désérialiseur personnalisé.

SimpleModule module = new SimpleModule("PeopleModule", new Version(1, 1, 0, null);
module.addDeserializer(Person.class, new JacksonPersonDeserializer());

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);

En alternance sur le Person elle-même, vous pouvez faire quelque chose comme :

class Person {

  @JsonDeserialize(using=JacksonPersonDeserializer.class)
  Person spouse;
}

Cela fonctionne avant 1.9 mais pollue votre objet. Dans tous les cas, vous devrez écrire un désérialiseur personnalisé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X