web-dev-qa-db-fra.com

Quel est l'équivalent Jackson de la désérialisation de @JsonUnwrapped?

Disons que j'ai la classe suivante:

public class Parent {
  public int age;
  @JsonUnwrapped
  public Name name;
}

Produire du JSON:

{
  "age" : 18,
  "first" : "Joey",
  "last" : "Sixpack"
}

Comment puis-je désérialiser cela dans la classe Parent? Je pourrais utiliser @JsonCreator

@JsonCreator
public Parent(Map<String,String> jsonMap) {
  age = jsonMap.get("age");
  name = new Name(jsonMap.get("first"), jsonMap.get("last"));
}

Mais cela ajoute également @JsonIgnoreProperties(ignoreUnknown=true) à la classe Parent, car toutes les propriétés sont mappées ici. Ainsi, si vous souhaitez que les champs JSON inconnus génèrent une exception, vous devez le faire vous-même. De plus, si les valeurs de la carte peuvent être autre chose que des chaînes, vous devrez effectuer une vérification de type et une conversion manuelles. Y a-t-il un moyen pour Jackson de gérer ce cas automatiquement?

Edit: Je suis peut-être fou, mais cela semble fonctionner même si cela n'a jamais été explicitement mentionné dans la documentation: http://fasterxml.github.io/jackson-annotations/javadoc/2.2.0 /com/fasterxml/jackson/annotation/JsonUnwrapped.html
J'étais à peu près sûr que cela ne fonctionnait pas pour moi auparavant. Néanmoins, l'approche proposée par @JsonCreator pourrait être préférable lorsqu'une logique personnalisée est requise pour désérialiser les types polymorphes non enveloppés.

35
Shaun

Vous pouvez utiliser @JsonCreator avec @JsonProperty pour chaque champ:

@JsonCreator
public Parent(@JsonProperty("age") Integer age, @JsonProperty("firstName") String firstName,
        @JsonProperty("lastName") String lastName) {
    this.age = age;
    this.name = new Name(firstName, lastName);
}

Jackson fait une vérification de type et une vérification de champ inconnu pour vous dans ce cas.

28
hoaz

Cela fonctionne également pour la désérialisation, bien que ce ne soit pas explicitement mentionné dans la documentation, comme vous l'avez dit. Voir le test unitaire de désérialisation de @JsonUnwrapped ici pour confirmation - https://github.com/FasterXML/jackson-databind/blob/d2c083a6220f2875c97c29f4823d9818972511dc/src/test/Java/com/fasterxml/jackcom Java # L138

3
spinlok

Pour ceux qui ont googlé ici comme moi, essayant de résoudre le problème lors de la désérialisation de la touche Map, il existe une solution avec @JsonAnySetter:

public class CountryList
{

    Map<String, Country> countries = new HashMap<>();

    @JsonAnySetter
    public void setCountry(String key, Country value)
    {
        countries.put(key, value);
    }

}
0
Jan Mares