【问题标题】:What are @JsonTypeInfo and @JsonSubTypes used for in jackson杰克逊中的@JsonTypeInfo 和@JsonSubTypes 是干什么用的
【发布时间】:2018-01-08 21:05:15
【问题描述】:

Jackson 中使用的@JsonTypeInfo@JsonSubTypes 注释是什么?

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

我的理解是,它还保留了被序列化的对象的具体类型以及实际数据。

我不清楚在反序列化过程中的实际优势/增益是什么。

除了 java 文档之外,没有得到任何重要的文档。任何人都可以在这里提供帮助或提供一些相同的文档。

【问题讨论】:

标签: java serialization jackson deserialization


【解决方案1】:

这些注释的目的是支持反序列化的多态性。当反序列化实际执行的代码时,将知道它所期望的。例如,被反序列化为的某些字段的类型。但是,如果该类具有子类(即子类型),通用 Jackson 反序列化器如何知道被反序列化的字符串是哪个实际类?它必须创建某个具体类型(类或其子类之一)的实例并填充它。它可以知道要创建哪一个的唯一方法是该信息是否首先写入到序列化中。

正如this answer 所说,有三种方法可以做到这一点 - 您选择适合您的用例的一种。 @JsonTypeInfo + @JsonSubtypes 是其中一种方式 - 当您在编译时知道相关类可能存在的所有可能子类型时,它会非常有效。

【讨论】:

  • 在各个具体类上使用@JsonTypeInfo 不是更有意义吗?在接口上使用它似乎违反了我认为的开闭原则(因为我们需要在每次添加具体实现时修改我们的接口)。如果这里遗漏了什么,请纠正我
  • 同样,这取决于用例。例如,我有一个用例,实际上我可以在一个地方使用@JsonSubtypes,这比标记每个子类型更可取。但是TBH我忘记了那个用例现在是什么;我记得这有点不寻常。但它更多地与实际的部署/发布问题有关,而不是纯粹的 O-O 理论。 (请记住:像开-关这样的任何“原则”都只是一个强有力的指导方针......在某些情况下,您可能会发现违反这样的原则是正确的设计 - 只要确保您真的知道为什么。)
  • 假设你有一个包含 Animal 类型字段的类 Cage。当 Cage 对象从 JSON 反序列化时,Jackson 发现它应该创建一个 Animal,因此如果 Animal 没有使用 @JsonTypeInfo 注释,Jackson 将不会应用对多态性的支持,因此它将只创建 Animal(如果可能)和不是它的子类型。
猜你喜欢
  • 1970-01-01
  • 2014-08-29
  • 1970-01-01
  • 2023-04-03
  • 1970-01-01
  • 2015-06-13
  • 2020-03-31
  • 2012-08-01
  • 1970-01-01
相关资源
最近更新 更多