web-dev-qa-db-fra.com

À quoi servent @JsonTypeInfo et @JsonSubTypes dans jackson

À quoi servent les annotations @JsonTypeInfo et @JsonSubTypes dans jackson?

public class Lion extends Animal {

private String name;

@JsonCreator
public Lion(@JsonProperty("name") String name) {
    this.name = name;
}

public String getName() {
    return name;
}

public String getSound() {
    return "Roar";
}

public String getType() {
    return "carnivorous";
}

public boolean isEndangered() {
    return true;
}

@Override
public String toString() {
    return "Lion [name=" + name + ", getName()=" + getName() + ", getSound()=" + getSound() + ", getType()=" + getType() + ", isEndangered()="
            + isEndangered() + "]";
}

}

========================================

public class Elephant extends Animal {

@JsonProperty
private String name;

@JsonCreator
public Elephant(@JsonProperty("name") String name) {
    this.name = name;
}

public String getName() {
    return name;
}

public String getSound() {
    return "trumpet";
}

public String getType() {
    return "herbivorous";
}

public boolean isEndangered() {
    return false;
}

@Override
public String toString() {
    return "Elephant [name=" + name + ", getName()=" + getName() + ", getSound()=" + getSound() + ", getType()=" + getType()
            + ", isEndangered()=" + isEndangered() + "]";
}
}

==============================================

@JsonTypeInfo (use = JsonTypeInfo.Id.CLASS, include = As.PROPERTY, property = "classNameExtenral")
@JsonSubTypes ({@Type (value = Lion.class, name = "lion"), @Type (value = Elephant.class, name = "elephant")})

public abstract class Animal {

@JsonProperty ("name")
String name;
@JsonProperty ("sound")
String sound;
@JsonProperty ("type")
String type;
@JsonProperty ("endangered")
boolean endangered;
}

public static void main(String[] args){
    Lion lion = new Lion("Simba");
    Elephant elephant = new Elephant("Manny");
    List<Animal> animals = new ArrayList<>();
    animals.add(lion);
    animals.add(elephant);
}

Ce que je comprends qu'il préserve en outre le type concret d'objet sérialisé avec les données réelles.

Ce qui n'est pas clair pour moi est quel est l'avantage/gain réel pendant la désérialisation.

Ne pas obtenir de documentation importante en dehors des documents Java. Can any1 peut-il aider ici ou fournir des documents autour de la même chose.

17
Harshit

Le but de ces annotations est de supporter le polymorphisme lors de la désérialisation. Lors de la désérialisation, le code en cours d'exécution connaîtra la classe de ce qu'il attend. Par exemple, le type d'un champ en cours de désérialisation. Mais si cette classe a des sous-classes (c'est-à-dire des sous-types), comment le désérialiseur Jackson générique sait-il de quelle classe est la chaîne en cours de désérialisation? Il faut créer une instance d'un type concret (la classe ou l'une de ses sous-classes) et la remplir. La seule façon de savoir lequel créer est de savoir si ces informations sont écrites dans la sérialisation en premier lieu.

Comme cette réponse dit qu'il y a trois façons de le faire - vous choisissez celle qui convient à votre cas d'utilisation. @JsonTypeInfo + @JsonSubtypes est l'un de ces moyens - il fonctionne très bien lorsque vous connaissez, au moment de la compilation, tous les sous-types possibles qui pourraient exister pour la classe en question.

25
davidbak