@JsonCreator
Jackson在反序列化的時候,會使用實體的默認(rèn)無參構(gòu)造函數(shù)來實例化一個對象,然后使用對象的setter方法來初始化屬性值,如果沒有定義無參構(gòu)造函數(shù)會發(fā)生什么呢,我們來看下
@AllArgsConstructor
@Getter
@Setter
class Player{
String name;
int age;
}
測試代碼如下
@Test
public void JsonCreatorTest() throws Exception{
CombineJacksonAnnotation.Player player = om.readValue("{\n" +
" \"name\" : \"tom\",\n" +
" \"age\" : 12" +
"}",CombineJacksonAnnotation.Player.class);
}
運行之后,會看到Jackson報錯
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `com.ittx.cbt.report.service.jackson.CombineJacksonAnnotation$Player` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
根據(jù)提示可以看到,在反序列化對象的時候,要提供默認(rèn)的無參構(gòu)造函數(shù),或是
delegate- or property-based Creator。
所以我們可以使用@JsonCreator來指定反序列化時候的構(gòu)造函數(shù),如下
@AllArgsConstructor
@Getter
@Setter
class Player{
@JsonCreator
public Player(@JsonProperty("name") String name){
this.name = name;
this.age =10;
System.out.println("test case");
}
String name;
int age;
}
再次運行測試代碼,結(jié)果如下

image.png
可以看到不報錯了,雖然我們在反序列化時候,實例化一個Player的時候?qū)ge初始化成了10,但是Jackson會繼續(xù)的使用setter方法將其賦值為12,注意在使用@JsonCreator指定反序列化構(gòu)造函數(shù)時,參數(shù)一定要使用@JsonProperty指定Json key的名稱。
@JsonEnumDefaultValue
此注解比較簡單,可以在反序列化枚舉時指定默認(rèn)的value,如下
enum Animal{
DOG,
@JsonEnumDefaultValue
CAT;
}
測試代碼如下

image.png
可以看到成功的反序列化到了DOG對象,但是如果我們改下代碼

image.png
可以看到當(dāng)反序列化找不到對象的時候,成功的反序列化成了CAT,注意此注解要生效,記得加上
om.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE);
當(dāng)人我們可以使用前面講的@JsonCreator來指定反序列化的構(gòu)造方法,代碼如下
enum Animal{
DOG,
@JsonEnumDefaultValue
CAT;
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
public static Animal animalValueOf( String type){
if(type.equals("dog")){
return DOG;
}
return null;
}
}
繼續(xù)運行代碼

image.png
可以看到這個時候animal被反序列化成了null,個人建議使用@JsonCreator來反序列化枚舉對象,這個靈活性和可控性更強。