Wofür werden @JsonTypeInfo und @JsonSubTypes in Jackson verwendet

Lesezeit: 3 Minuten

Benutzeravatar von Harshit
Hart

Was sind die @JsonTypeInfo Und @JsonSubTypes Anmerkungen für in Jackson verwendet?

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);
}

Was ich verstehe ist dass es zusätzlich den konkreten Typ des zu serialisierenden Objekts zusammen mit den tatsächlichen Daten beibehält.

Was ist mir nicht klar ist der tatsächliche Vorteil/Gewinn während der Deserialisierung.

Abgesehen von den Java-Dokumenten wird keine signifikante Dokumentation erhalten. Kann jemand bitte hier helfen oder einige Dokumente zur Verfügung stellen.

  • Vielleicht hilft diese Antwort: stackoverflow.com/a/31666888/751579

    – davidbak

    1. August 2017 um 21:07 Uhr

  • Es hilft … danke.

    – Hart

    1. August 2017 um 21:32 Uhr

Benutzeravatar von davidbak
davidbak

Der Zweck dieser Anmerkungen ist die Unterstützung Polymorphismus auf Deserialisierung. Beim Deserialisieren wird der tatsächlich ausgeführte Code die kennen Klasse von dem, was es erwartet. ZB der Typ eines Feldes, in das deserialisiert wird. Aber wenn diese Klasse Unterklassen (dh Untertypen) hat, woher weiß der generische Jackson-Deserialisierer, welche tatsächliche Klasse die zu deserialisierende Zeichenfolge ist? Es muss eine Instanz eines konkreten Typs (der Klasse oder einer ihrer Unterklassen) erstellen und füllen. Es kann nur wissen, welches erstellt werden soll, wenn diese Informationen vorhanden sind geschrieben in erster Linie in die Serialisierung.

Wie diese Antwort sagt, gibt es drei Möglichkeiten, dies zu tun – Sie wählen diejenige aus, die für Ihren Anwendungsfall geeignet ist. @JsonTypeInfo + @JsonSubtypes ist eine dieser Möglichkeiten – es funktioniert hervorragend, wenn Sie zur Kompilierzeit alle möglichen Untertypen kennen, die für die betreffende Klasse existieren könnten.

  • Ist die Verwendung von @JsonTypeInfo für die einzelnen konkreten Klassen nicht sinnvoller? Die Verwendung über die Schnittstelle scheint das Open-Close-Prinzip zu verletzen, nehme ich an (da wir unsere Schnittstelle bei jeder neuen Hinzufügung einer konkreten Implementierung ändern müssen). Bitte korrigieren Sie mich, wenn ich hier etwas vermisse

    – Hart

    1. August 2017 um 22:02 Uhr

  • Auch hier kommt es wieder auf den Anwendungsfall an. Zum Beispiel hatte ich einen Anwendungsfall, in dem ich tatsächlich @JsonSubtypes an einer Stelle verwenden konnte, und das war dem Taggen jedes Untertyps vorzuziehen. Aber TBH, ich vergesse jetzt, was dieser Anwendungsfall war; Ich erinnere mich, dass es etwas ungewöhnlich war. Aber es hatte mehr mit praktischen Bereitstellungs-/Veröffentlichungsproblemen zu tun als mit reiner OO-Theorie. (Denken Sie daran: Jedes “Prinzip” wie Open-Close ist nur eine starke Richtlinie … Sie werden in einigen Fällen feststellen, dass die Verletzung eines solchen Prinzips ein korrektes Design ist – stellen Sie nur sicher, dass Sie wirklich wissen, warum.)

    – davidbak

    1. August 2017 um 23:10 Uhr

  • Stellen Sie sich vor, Sie haben eine Klasse Cage, die ein Feld vom Typ Animal enthält. Wenn das Cage-Objekt von JSON deserialisiert wird, stellt Jackson fest, dass es ein Tier erstellen sollte. Wenn also Animal nicht mit @JsonTypeInfo kommentiert ist, wendet Jackson die Unterstützung für Polymorphismus nicht an und erstellt daher nur Animal (falls möglich) und nicht sein Subtyp.

    – Konstantin Pelepelin

    4. September 2017 um 19:22 Uhr

1449630cookie-checkWofür werden @JsonTypeInfo und @JsonSubTypes in Jackson verwendet

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy