Jackson對多態和多子類序列化的處理配置

異常:

Can not construct instance of XXXX, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information

jackson容許配置多態類型處理,當進行反序列話時,JSON數據匹配的對象可能有多個子類型,爲了正確的讀取對象的類型,咱們須要添加一些類型信息。能夠經過下面幾個註解來實現:數組

interface

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@clazz")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Terms4AccuracyLevelVo.class, name = "AccuracyLevel"),
        @JsonSubTypes.Type(value = Terms4AnswerCidVo.class, name = "AnswerCid"),
        @JsonSubTypes.Type(value = Terms4IsRightVo.class, name = "IsRight"),
})
public interface ITerms extends Comparable<ITerms>, Serializable {
    ... ...
}

class

@Data
@NoArgsConstructor
@ApiModel(value = "準確度等級統計", description = "準確度等級統計")
public class Terms4AccuracyLevelVo implements ITerms {
    ... ...
}
@Data
@NoArgsConstructor
@ApiModel(value = "答案內容統計", description = "答案內容統計")
public class Terms4AnswerCidVo implements ITerms {
    ... ...
}
@Data
@NoArgsConstructor
@ApiModel(value = "答案對錯統計", description = "答案對錯統計")
public class Terms4IsRightVo implements ITerms {
    ... ...
}

@JsonTypeInfo

use:定義使用哪種類型識別碼,它有下面幾個可選值:
    1JsonTypeInfo.Id.CLASS:使用徹底限定類名作識別
    2JsonTypeInfo.Id.MINIMAL_CLASS:若基類和子類在同一包類,使用類名(忽略包名)做爲識別碼
    3JsonTypeInfo.Id.NAME:一個合乎邏輯的指定名稱
    4JsonTypeInfo.Id.CUSTOM:自定義識別碼,由@JsonTypeIdResolver對應,稍後解釋
    5JsonTypeInfo.Id.NONE:不使用識別碼
include(可選):指定識別碼是如何被包含進去的,它有下面幾個可選值:
    1JsonTypeInfo.As.PROPERTY:做爲數據的兄弟屬性
    2JsonTypeInfo.As.EXISTING_PROPERTY:做爲POJO中已經存在的屬性
    3JsonTypeInfo.As.EXTERNAL_PROPERTY:做爲擴展屬性
    4JsonTypeInfo.As.WRAPPER_OBJECT:做爲一個包裝的對象
    5JsonTypeInfo.As.WRAPPER_ARRAY:做爲一個包裝的數組
property(可選):制定識別碼的屬性名稱
    此屬性只有當use爲
        JsonTypeInfo.Id.CLASS(若不指定property則默認爲@classJsonTypeInfo.Id.MINIMAL_CLASS(若不指定property則默認爲@c)
        JsonTypeInfo.Id.NAME(若不指定property默認爲@type)
    include爲JsonTypeInfo.As.PROPERTYJsonTypeInfo.As.EXISTING_PROPERTY、JsonTypeInfo.As.EXTERNAL_PROPERTY時纔有效
defaultImpl(可選):若是類型識別碼不存在或者無效,能夠使用該屬性來制定反序列化時使用的默認類型
visible(可選,默認爲false):是否可見
    屬性定義了類型標識符的值是否會經過JSON流成爲反序列化器的一部分,默認爲fale,也就是說,jackson會從JSON內容中處理和刪除類型標識符再傳遞給JsonDeserializer

@JsonSubTypes

做用於類/接口,用來列出給定類的子類,只有當子類類型沒法被檢測到時纔會使用它
通常是配合@JsonTypeInfo在基類上使用,好比:app

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS, include = JsonTypeInfo.As.PROPERTY, property = "@clazz")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Terms4AccuracyLevelVo.class, name = "AccuracyLevel"),
        @JsonSubTypes.Type(value = Terms4AnswerCidVo.class, name = "AnswerCid"),
        @JsonSubTypes.Type(value = Terms4IsRightVo.class, name = "IsRight"),
})

@JsonSubTypes

@JsonSubTypes.Type[] 數組,裏面枚舉了多態類型(value對應類)和類型的標識符值(name對應@JsonTypeInfo中的property標識名稱的值,此爲可選值,若不制定需由@JsonTypeName在子類上制定) ,如:spa

@Data
@NoArgsConstructor
@ApiModel(value = "答案對錯統計", description = "答案對錯統計")
@JsonTypeName(value = "IsRight")
public class Terms4IsRightVo implements ITerms {
    ... ...
}
相關文章
相關標籤/搜索