1. 概述
本教程將演示如何使用 Jackson 2.x 在將對象序列化為 JSON 時 忽略某些字段。
當 Jackson 的默認設置不足時,並且我們需要精確控制哪些字段序列化到 JSON 中,這非常有用,並且有多種方法可以忽略屬性。
要深入瞭解並學習更多關於 Jackson 的用法,請訪問主 Jackson 教程。
2. 忽略類級別字段
我們可以使用 @JsonIgnoreProperties 註解,並指定字段名稱來忽略特定類級別字段:
@JsonIgnoreProperties(value = { "intValue" })
public class MyDto {
private String stringValue;
private int intValue;
private boolean booleanValue;
public MyDto() {
super();
}
// standard setters and getters are not shown
}我們現在可以測試一下,在將對象寫入 JSON 後,該字段確實不在輸出中。
@Test
public void givenFieldIsIgnoredByName_whenDtoIsSerialized_thenCorrect()
throws JsonParseException, IOException {
ObjectMapper mapper = new ObjectMapper();
MyDto dtoObject = new MyDto();
String dtoAsString = mapper.writeValueAsString(dtoObject);
assertThat(dtoAsString, not(containsString("intValue")));
}3. 忽略字段級別字段
我們還可以通過在字段上直接使用 @JsonIgnore 註解 直接忽略字段:
public class MyDto {
private String stringValue;
@JsonIgnore
private int intValue;
private boolean booleanValue;
public MyDto() {
super();
}
// standard setters and getters are not shown
}我們現在可以測試intValue字段確實不在序列化的JSON輸出中。
@Test
public void givenFieldIsIgnoredDirectly_whenDtoIsSerialized_thenCorrect()
throws JsonParseException, IOException {
ObjectMapper mapper = new ObjectMapper();
MyDto dtoObject = new MyDto();
String dtoAsString = mapper.writeValueAsString(dtoObject);
assertThat(dtoAsString, not(containsString("intValue")));
}4. 忽略指定類型的所有字段
最後,我們可以使用 @JsonIgnoreType 註解忽略指定類型的所有字段。如果控制了字段類型,則可以直接對類進行標註:
@JsonIgnoreType
public class SomeType { ... }通常情況下,我們並不能控制該類本身。在這種情況下,我們可以充分利用 Jackson 混合模式。
首先,我們為想要忽略和標記的類型定義一個混合模式,並在其中添加 @JsonIgnoreType 註解:
@JsonIgnoreType
public class MyMixInForIgnoreType {}然後,我們註冊該 Mixin 以替換(並忽略)所有 String[] 類型在序列化過程中。
mapper.addMixInAnnotations(String[].class, MyMixInForIgnoreType.class);此時,所有字符串數組將被忽略,而不是轉換為 JSON。
@Test
public final void givenFieldTypeIsIgnored_whenDtoIsSerialized_thenCorrect()
throws JsonParseException, IOException {
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(String[].class, MyMixInForIgnoreType.class);
MyDtoWithSpecialField dtoObject = new MyDtoWithSpecialField();
dtoObject.setBooleanValue(true);
String dtoAsString = mapper.writeValueAsString(dtoObject);
assertThat(dtoAsString, containsString("intValue"));
assertThat(dtoAsString, containsString("booleanValue"));
assertThat(dtoAsString, not(containsString("stringValue")));
}以下是我們的 DTO:
public class MyDtoWithSpecialField {
private String[] stringValue;
private int intValue;
private boolean booleanValue;
}注意:自版本 2.5 以來,我們似乎無法使用此方法來忽略基本數據類型,但可以用於自定義數據類型和數組。
5. 忽略使用過濾器字段
最後,我們還可以使用過濾器來忽略 Jackson 中的特定字段。
首先,我們需要在 Java 對象上定義過濾器:
@JsonFilter("myFilter")
public class MyDtoWithFilter { ... }然後我們定義一個簡單的過濾器,它將忽略 intValue 字段:
SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter
.serializeAllExcept("intValue");
FilterProvider filters = new SimpleFilterProvider()
.addFilter("myFilter", theFilter);現在我們可以序列化對象,並確保 JSON 輸出中不存在 intValue 字段:
@Test
public final void givenTypeHasFilterThatIgnoresFieldByName_whenDtoIsSerialized_thenCorrect()
throws JsonParseException, IOException {
ObjectMapper mapper = new ObjectMapper();
SimpleBeanPropertyFilter theFilter = SimpleBeanPropertyFilter
.serializeAllExcept("intValue");
FilterProvider filters = new SimpleFilterProvider()
.addFilter("myFilter", theFilter);
MyDtoWithFilter dtoObject = new MyDtoWithFilter();
String dtoAsString = mapper.writer(filters).writeValueAsString(dtoObject);
assertThat(dtoAsString, not(containsString("intValue")));
assertThat(dtoAsString, containsString("booleanValue"));
assertThat(dtoAsString, containsString("stringValue"));
System.out.println(dtoAsString);
}6. 結論
本文闡述瞭如何忽略序列化過程中的字段。我們首先通過名稱進行忽略,然後直接忽略,最後通過使用 MixIns 忽略整個 Java 類型,並結合過濾器以獲得對輸出的更精細控制。