在 Jackson 映射中將默認值設置為 Null 字段
1. 概述
在本教程中,我們將了解使用 Jackson 解析 JSON String
時處理null
或缺失值的不同方法。我們將詳細探討三個選項,它們提供不同級別的控制。
2. 不帶註釋設置默認值
我們將看到的第一個示例是,當傳入的 JSON String
完全缺少默認值時,如何將默認值添加到 POJO 中。讓我們創建一個包含兩個字段的對象,一個是必需的,另一個是我們設置默認值的:
class NonAnnotatedDefaultValue {
String required;
String optional = "defaultValue";
// Standard getters and setters
}
我們在這里為名為optional
的字段分配了一個值。如果 JSON 中缺少該字段,這將導致 Jackson 使用該String
。現在讓我們通過要求 Jackson 映射一個 JSON String
來使用該對象,其中不包含名為optional
的字段。我們將使用ObjectMapper
對象及其readValue()
方法:
@Test
void givenAClassWithADefaultValue_whenReadingJsonWithoutOptionalValue_thenExpectDefaultValueInResult()
throws JsonProcessingException {
String noOptionalField = "{\"required\": \"value\"}";
ObjectMapper objectMapper = new ObjectMapper();
NonAnnotatedDefaultValue createdObject = objectMapper.readValue(noOptionalField, NonAnnotatedDefaultValue.class);
assert(createdObject.getRequired()).equals("value");
assert(createdObject.getOptional()).equals("defaultValue");
}
從斷言中我們可以看到,生成的對象既有 JSON 中的值,也有我們之前指定的默認值。
此方法的缺點是,僅當傳入的 JSON 中完全缺少該屬性時,它才有效。如果該屬性存在null
值,則 Jackson 將不會應用默認值。在下面的部分中,我們將看到可以讓我們更好地處理null
的方法。
3.使用JsonSetter
進行最大程度的控制
我們可以使用@JsonSetter
註釋來完全控制映射過程。讓我們使用註釋創建一個對象:
class JsonSetterDefaultValue {
String required;
String optional = "valueIfMissingEntirely";
@JsonSetter("optional")
public void setOptional(String optional) {
if (optional == null) {
this.optional = "valueIfNull";
}
}
// Standard getters and setters
}
在這裡,我們像以前一樣在類級別提供了默認值。但是,我們還提供了一個 setter 方法並用@JsonSetter
對其進行註釋。在該 setter 方法中,我們現在可以做任何我們喜歡的事情。在此示例中,我們明確提供了值為null
時的預期行為。如果我們不將屬性包含在 JSON 中,Jackson 現在將把optional
設置為valueIfMissingEntirely
“\,如果包含該屬性,則將valueIfNull
設置為null
。
如果滿足我們的要求,我們可以使這兩個值相同。讓我們看看實際情況:
@Test
void givenAClassWithAJsonSetter_whenReadingJsonWithNullOptionalValue_thenExpectDefaultValueInResult()
throws JsonProcessingException {
String nullOptionalField = "{\"required\": \"value\", \"optional\": null}";
ObjectMapper objectMapper = new ObjectMapper();
JsonSetterDefaultValue createdObject = objectMapper.readValue(nullOptionalField, JsonSetterDefaultValue.class);
assert(createdObject.getRequired()).equals("value");
assert(createdObject.getOptional()).equals("valueIfNull");
}
在這裡,我們提供了 JSON,其中名為optional
字段設置為null
。我們可以從斷言中看到,在 Jackson 創建的結果對像中,由於我們的註釋valueIfNull,
。這個選項為我們的方法提供了巨大的靈活性。如果我們願意,我們還可以檢查空String
並以相同的方式應用默認值。
4.使用JsonSetter
和Nulls.SKIP
我們最後的選擇再次使用@JsonSetter
,但擴展了用法以告訴它忽略null
。讓我們創建一個新類:
class NullsSkipDefaultValue {
private String required;
@JsonSetter(nulls = Nulls.SKIP)
private String optional = "defaultValue";
// standard getters and setters
}
Nulls.SKIP
參數告訴@JsonSetter
跳過任何具有null
值的輸入。然後 Jackson 使用提供的默認值。我們可以使用Nulls
枚舉中的其他幾個選項。例如, Nulls.SET
將告訴 Jackson 將 JSON 中的null
轉換為 POJO 中的 Java null
。今天我們將繼續使用Nulls.SKIP
:
@Test
void givenAClassWithAJsonSetterNullsSkip_whenReadingJsonWithNullOptionalValue_thenExpectDefaultValueInResult() throws JsonProcessingException {
String nullOptionalField = "{\"required\": \"value\", \"optional\": null}";
ObjectMapper objectMapper = new ObjectMapper();
NullsSkipDefaultValue createdObject = objectMapper.readValue(nullOptionalField, NullsSkipDefaultValue.class);
assert(createdObject.getRequired()).equals("value");
assert(createdObject.getOptional()).equals("defaultValue");
}
在上面,我們可以看到,給定與第 3 節中相同的輸入 JSON,其中optional
字段被分配為null
,我們得到了我們想要的默認值。如果我們不提供可選字段,這也會給出相同的結果。
5. 結論
在本文中,我們探索了三種處理 JSON 中缺失值或null
的方法,我們希望使用 Jackson 對其進行解析。
在類級別設置值很有用,但如果我們null
值,則會失敗。我們可以在 setter 方法上使用@JsonSetter
註釋來實現最大程度的控制。或者,我們可以在字段聲明上使用@JsonSetter
來簡單地忽略null
。根據我們的用例,這三種方法可能都適合。最重要的考慮因素是我們希望應用程序如何處理值為null
的屬性。
與往常一樣,示例的完整代碼可在 GitHub 上獲取。