2017-08-01 61 views
5

jackson中使用for的@JsonTypeInfo和@JsonSubTypes註解是什麼?什麼是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文檔,沒有得到任何重要的文檔。任何1請幫助這裏或提供一些相同的文檔。

+0

也許這個答案將幫助:https://stackoverflow.com/a/31666888/751579 – davidbak

+0

它幫助..謝謝。 – Harshit

回答

6

這些註釋的目的是支持關於反序列化的多態性。反序列化正在執行的實際代碼將知道它期望的類別。例如,一些被反序列化的字段的類型。但是,如果該類有子類(即,子類型),通用Jackson反序列化器如何知道被反序列化的字符串是哪個實際類?它需要創建一些具體類型的實例(類或它的一個子類)並填充它。如果該信息是首先將寫入序列化,那麼它可以知道創建哪個的唯一方法。

由於this answer表示有三種方法可以做到 - 選擇適合您的用例的方法。 @JsonTypeInfo + @JsonSubtypes就是其中一種方式 - 當您在編譯時知道所討論的類可能存在的所有可能的子類型時,它會很好用。

+0

對個別具體類不使用@JsonTypeInfo更有意義嗎?在接口上使用它似乎違反了我認爲的開放 - 關閉原則(因爲我們需要修改每個新增的具體實現的接口)。如果我在這裏丟失了某些東西,請糾正我的錯誤 – Harshit

+0

這又取決於用例。例如,我有一個用例,我實際上可以在一個地方使用@JsonSubtypes,並且最好爲每個子類型添加標籤。但是TBH我忘記了現在的用例;我記得這有點不同尋常。但它與純粹的O-O理論相關的實際部署/發佈問題更多。 (記住:任何「原則」就像開放關閉只是一個強有力的指導方針......在某些情況下,您可能會發現違反這種原則是正確的設計 - 只要確保您真的知道爲什麼。) – davidbak

+1

考慮你有一個類籠其中包含一個動物類型的字段。當Cage對象從JSON反序列化時,Jackson發現它應該創建一個Animal,所以如果Animal沒有使用@JsonTypeInfo註釋,那麼Jackson將不會應用對多態的支持,所以它會創建Animal(如果可能)和不是它的亞型。 –

相關問題