原文鏈接:https://www.jianshu.com/p/a21f1633d79c
-
jackson允許配置多態類型處理,當進行反序列話時,JSON數據匹配的對象可能有多個子類型,為了正確的讀取對象的類型,我們需要添加一些類型信息。可以通過下面幾個注解來實現:
-
@JsonTypeInfo
作用於類/接口,被用來開啟多態類型處理,對基類/接口和子類/實現類都有效 -
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,include = JsonTypeInfo.As.PROPERTY,property = "name")
這個注解有一些屬性:- use:定義使用哪一種類型識別碼,它有下面幾個可選值:
-
JsonTypeInfo.Id.CLASS
:使用完全限定類名做識別 -
JsonTypeInfo.Id.MINIMAL_CLASS
:若基類和子類在同一包類,使用類名(忽略包名)作為識別碼 -
JsonTypeInfo.Id.NAME
:一個合乎邏輯的指定名稱 -
JsonTypeInfo.Id.CUSTOM
:自定義識別碼,由@JsonTypeIdResolver
對應,稍后解釋 -
JsonTypeInfo.Id.NONE
:不使用識別碼
-
- include(可選):指定識別碼是如何被包含進去的,它有下面幾個可選值:
- JsonTypeInfo.As.PROPERTY:作為數據的兄弟屬性
- JsonTypeInfo.As.EXISTING_PROPERTY:作為POJO中已經存在的屬性
- JsonTypeInfo.As.EXTERNAL_PROPERTY:作為擴展屬性
- JsonTypeInfo.As.WRAPPER_OBJECT:作為一個包裝的對象
- JsonTypeInfo.As.WRAPPER_ARRAY:作為一個包裝的數組
- property(可選):制定識別碼的屬性名稱
此屬性只有當:-
use
為JsonTypeInfo.Id.CLASS
(若不指定property則默認為@class
)、JsonTypeInfo.Id.MINIMAL_CLASS
(若不指定property則默認為@c
)、JsonTypeInfo.Id.NAME
(若不指定property默認為@type
), -
include
為JsonTypeInfo.As.PROPERTY
、JsonTypeInfo.As.EXISTING_PROPERTY
、JsonTypeInfo.As.EXTERNAL_PROPERTY
時才有效
-
-
defaultImpl
(可選):如果類型識別碼不存在或者無效,可以使用該屬性來制定反序列化時使用的默認類型 - visible(可選,默認為false):是否可見
屬性定義了類型標識符的值是否會通過JSON流成為反序列化器的一部分,默認為fale,也就是說,jackson會從JSON內容中處理和刪除類型標識符再傳遞給JsonDeserializer。
- use:定義使用哪一種類型識別碼,它有下面幾個可選值:
-
@JsonSubTypes
作用於類/接口,用來列出給定類的子類,只有當子類類型無法被檢測到時才會使用它,一般是配合@JsonTypeInfo在基類上使用,比如:@JsonTypeInfo(use = JsonTypeInfo.Id.NAME,include = JsonTypeInfo.As.PROPERTY,property = "typeName") @JsonSubTypes({@JsonSubTypes.Type(value=Sub1.class,name = "sub1"),@JsonSubTypes.Type(value=Sub2.class,name = "sub2")})
@JsonSubTypes
的值是一個@JsonSubTypes.Type[]
數組,里面枚舉了多態類型(value
對應子類)和類型的標識符值(name
對應@JsonTypeInfo
中的property標識名稱的值,此為可選值,若不制定需由@JsonTypeName
在子類上制定)
@JsonTypeName
作用於子類,用來為多態子類指定類型標識符的值
比如:@JsonTypeName(value = "sub1")
示例
- 基類:
@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS,property = "type") @JsonSubTypes({@JsonSubTypes.Type(value= Test.RoleUser.class,name = "role"),@JsonSubTypes.Type(value= Test.TokenUser.class,name = "token")}) public abstract class AbstractBaseEntity { private String userName; private String password; public String getUserName() { return userName; } public AbstractBaseEntity setUserName(String userName) { this.userName = userName; return this; } public String getPassword() { return password; } public AbstractBaseEntity setPassword(String password) { this.password = password; return this; } @Override public String toString() { final StringBuffer sb = new StringBuffer("AbstractBaseEntity{"); sb.append("userName='").append(userName).append('\''); sb.append(", password='").append(password).append('\''); sb.append('}'); return sb.toString(); } }
- 測試類
import com.fasterxml.jackson.databind.ObjectMapper; /** * @author micocube * projectName: utils4j * packageName: jackson * email: ldscube@gmail.com * createTime: 2019-07-05 11:23 * version: 0.1 * description: */ public class Test { # 子類 public static class TokenUser extends AbstractBaseEntity { private String token; public String getToken() { return token; } public TokenUser setToken(String token) { this.token = token; return this; }