java json註解

(1)初級
我們從幾個簡單的使用場景開始:重命名屬性,忽略屬性,以及修改屬性所使用的類型。
注意:下面的例子僅僅顯示了成員屬性(field properties),註解同樣也可以用在成員方法(getter/setter)上。
①屬性重命名時使用的註解
最常見的使用方式之一就是改變某個成員屬性所使用的JSON名稱,例如:

public class Name {
  @JsonProperty("firstName")
  public String _first_name;
}

將會生成如下所示的JSON數據結果:
{ "firstName" : "Bob" }

而不是:
{ "_first_name" : "Bob"}

②忽略屬性時使用的註解
有時POJO包括了一些你不希望輸出的屬性,在這種情況下,你可以進行如下操作:
public class Value {
  public int value;
  @JsonIgnore public int internalValue;
}

這時得到的JSON數據結果如下:
{ "value" : 42 }

或者,你可能忽略掉某些從JSON數據中得到的屬性,如果是這樣,你可以使用:
@JsonIgnoreProperties({ "extra", "uselessValue" })
public class Value {
  public int value;
}

這樣就能夠處理像如下所示的JSON數據:
{ "value" : 42, "extra" : "fluffy", "uselessValue" : -13 }

最後,你甚至能簡單地忽略掉從JSON(由於在應用中沒有完全匹配的POJO)中獲得的所有“多餘的”屬性。你可以通過添加如下代碼完成這個操作:
@JsonIgnoreProperties(ignoreUnknown=true)
public class PojoWithAny {
  public int value;
}

③選擇更多/更少(more/less)指定類型(specific types)時使用的註解
在有些情況下,Jackson在讀入或輸出一個成員屬性時,所選用的類型(type)可能並不是你想要的:
?當讀取(反序列化)時,聲明的類型(declared type)可能是一個基本類型(general type),但是你確切地知道應該使用的實現類型(譯註:也就說,我們需要反序列化後生成的對象是實現類型的);
?當輸出(序列化)時,Jackson默認使用的是給定的運行時類型(the specific runtime type);但是你可能不想輸出那個類型的所有信息,而僅僅是它的父類型所囊括的信息。
在這些應用場景,你可以使用如下的註解進行處理:
public class ValueContainer {
  // 雖然代碼中使用的類型(type)是'Value', 但我們希望讀取到的JSON 之後得到的對象的類型是'ValueImpl'
  @JsonDeserialize(as=ValueImpl.class)
  public Value value;

  // 雖然運行時的類型(type)可能是'AdvancedType'(高級類型), 但是我們確實想序列化
  // 成爲'BasicType'(基礎類型); 有兩種處理方式:
  @JsonSerialize(as=BasicType.class)
  // 或者我們可以這樣: @JsonSerialize(typing=Typing.STATIC)
  public BasicType another;
}

(2)中級
①使用構造器或工廠方法
在默認情況下,當由JSON數據創建相應類的實例時,Jackson嘗試使用該類的“默認”構造器(即無參數構造器)。不過,你可以選擇使用其他的構造器,或者一個靜態工廠方法,來創建實例。完成這個操作,你需要使用@JsonCreator註解,有可能還需要使用@JsonProperty註解給參數(arguments)綁定名稱。
public class CtorPOJO {
   private final int _x, _y;

   @JsonCreator
   public CtorPOJO(@JsonProperty("x") int x, @JsonProperty("y") int y) {
      _x = x;
      _y = y;
   }
}

使用相同的方式,可以將@JsonCreator用在靜態工廠方法上。不過,還有一個可選的替代方案,被稱作“授權式”構建器(“delegating” creator):

public class DelegatingPOJO {
   private final int _x, _y;

   @JsonCreator
   public DelegatingPOJO(Map<String,Object> delegate) {
      _x = (Integer) delegate.get("x");
      _y = (Integer) delegate.get("y");
   }
}

不同之處在於,構建器方法只能有一個參數,而且參數一定不要(must NOT)添加@JsonProperty註解。

②處理多態類型(polymorphic types)
如果你要進行讀取、輸出操作的對象擁有許多可能的子類型(即表現出多態性),你可能還需要添加一些類型信息。Jackson在反序列化時(讀取JSON數據,生成相應的對象)需要這些信息,以便能正確地讀取對象的類型。我們可以通過在“基本類型”上添加@JsonTypeInfo註解來完成操作:
//將Java類的名稱(“com.myempl.ImplClass”)存儲到JSON的一個名稱爲“class”的屬性中
@JsonTypeInfo(use=Id.CLASS, include=As.PROPERTY,property=”class”)
public abstract class BaseClass {
}

public class Impl1 extends BaseClass {
public int x;
}

public class Impl2 extends BaseClass {
public String name;
}

public class PojoWithTypedObjects {
public List<BaseClass> items;
}

這樣,序列化之後的JSON格式如下:
{“items” : [
{“class”:”Impl2”,  “name”: “Bob”},
{“class”:”Impl1”, :”x” : 13}
]}

注意:這個註解還有很多配置可以進行設置,詳細內容請查閱瀏覽:
? Javadocs
? 多態類型處理簡介I(ntro to polymorphic type handling)


③重新設置屬性的自動發現(Changing property auto-detection)
Jackson默認的屬性發現規則將會查找到如下所述的屬性:
?所有被public修飾的字段(成員變量);
?所有被public修飾的getter(即形如“getXxx()”的方法);
?所有被public修飾的setter(即形如“setXxx(value)”的方法),不管可見或不可見。
不過如果這樣也不行,你可以通過使用使用註解@JsonAutoDetect來改變可見級別。如果你想自動發現所有的字段(就像GSON包所進行的操作那樣),你可以這樣做:
@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.ANY)
public class POJOWithFields {
private int value;
}
或者,你想禁用對所有字段的自動發現:
@JsonAutoDetect(fieldVisibility=JsonAutoDetect.Visibility.NONE)
public class POJOWithNoFields {
//不會被序列化,除非再有一個可以訪問的“getValue”方法
public int value;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章