知識庫 / JSON / Jackson RSS 訂閱

將默認值設為空字段(Jackson 映射)

Jackson
HongKong
10
09:47 PM · Dec 05 ,2025

1. 概述

由於其相對的簡潔性和健壯性,JSON(JavaScript Object Notation)已成為人類可讀性和機器解析方面首選的數據格式。然而,某些JSON對象和屬性可能存在一些問題,需要進行特殊處理。

在本教程中,我們將探討使用Jackson解析JSON字符串時處理null或缺失值的不同方法。 尤其是,我們將探索三種具有不同控制級別的選項。

2. 在類級別設置默認值

為了説明如何在缺少來自傳入 JSON String 的所有完全默認值的情況下,獲取 POJOs 中的默認值,我們先演示一下。

例如,我們創建一個具有兩個字段的對象,一個 必需的,另一個 可選的,都使用各自的名稱:

class NonAnnotatedDefaultValue {
    String required;
    String optional = "defaultValue";
    // Standard getters and setters
}

因此,我們只為名為 optional 的字段分配了一個值。由於此原因,Jackson 在接收到的 JSON 對象中缺少該字段時,會使用預定義的 String

為了演示,讓我們使用新的對象,並要求 Jackson 將一個沒有名為 optional 的字段的 JSON String 進行映射。為此,請使用 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. 實現可選字段的設置方法以獲得完全控制權

當然,通過為我們想要提供值的可選字段實現設置方法,我們可以完全控制映射過程。

因此,讓我們創建一個包含所需設置方法的對象,Jackson 在創建對象時會使用它:

class SetterDefaultValue {
   String required;
   String optional = "valueIfMissingEntirely";

    public void setOptional(String optional) {
        if (optional == null) {
            this.optional = "valueIfNull";
        }
    }
   // Standard getters and setters
}

因此,我們仍然在類級別提供了默認值。但是,我們還提供了設置方法。在該設置方法中,我們可以執行任何所需的檢查。在本例中,我們明確地提供瞭如果值是null時的預期行為。

Jackson 現在將optional設置為valueIfMissingEntirely,如果未在 JSON 中包含該屬性,或者如果包含該屬性但設置為null時設置為valueIfNull

我們也可以使這兩個值相同,如果滿足要求:

@Test
void givenAClassWithASetter_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,這要歸功於 setter 註解

這使得通用的 setter 方法非常靈活。例如,我們也可以檢查空 String 並且以相同的方式應用默認值,如果需要或要求。

此外,setter 還可以更復雜。

4. 將空字符串解析為空字符串

在前面介紹的方法基礎上,我們可以使用 setter 方法將 null 值解析為空字符串,應用於 optional 字段

讓我們再次創建一個 POJO 類,其中包含 setter 方法,以便 Jackson 根據需要創建對象:

class SetterDefaultValueAsEmptyString {
    String required;
    String optional = "valueIfMissingEntirely";

    public void setOptional(String optional) {
        if (optional == null) {
            this.optional = "";
        }
    }
    
    // Standard getters and setters
}

在 setter 方法中,我們明確定義了對 null 值的預期行為。 Jackson 在我們未在 JSON 中包含該屬性時,會將 optional 字段設置為 valueIfMissingEntirely,正如之前一樣。 但是,現在它還會在包含該屬性但將其設置為 null 時,將 optional 字段設置為空字符串。

讓我們使用一個測試方法來驗證 null 值被映射為空字符串:

@Test
public void givenAClassWithASetter_whenReadingJsonWithNullOptionalValue_thenEmptyStringInResult() throws JsonProcessingException {
    String nullOptionalField = "{\"required\": \"value\", \"optional\": null}";
    ObjectMapper objectMapper = new ObjectMapper();
    SetterDefaultValueAsEmptyString createdObject = objectMapper.readValue(nullOptionalField, SetterDefaultValueAsEmptyString.class);
    assert(createdObject.getRequired()).equals("value");
    assert(createdObject.getOptional()).equals("");
}

本次,提供的JSON中,optional 字段的值設置為 null。 如我們所見,Jackson生成的斷言結果表明,生成的對象中包含一個字段,其值為一個空字符串。

5. 使用 @JsonSetter 配合 Nulls.SKIP

該選項利用了 @JsonSetter 並擴展了其用法,使其能夠忽略 null 值。

讓我們創建一個新的類:

class NullsSkipDefaultValue {
    private String required;
    @JsonSetter(nulls = Nulls.SKIP)
    private String optional = "defaultValue";
    // standard getters and setters
}

The Nulls.SKIP 參數指示 @JsonSetter 跳過任何值為 null 的輸入。Jackson 則使用提供的默認值。還有 多種其他選項 可在 Nulls 枚舉中使用。例如,Nulls.SET 告訴 Jackson 將 JSON 中的 null 翻譯為 POJO 中的 Java null

@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");
}

上面,我們可以看到,給定輸入 JSON,其中可選字段被賦值為null時,我們得到了期望的默認值。此方法在不提供可選字段時也產生相同的結果。

6. 結論

在本文中,我們探討了四種處理 JSON 中缺失或 null 值的方法,這些值我們將使用 Jackson 解析。

將值設置為類級別是有用的,但如果存在 null 值,則會失敗。相反,我們可以實現設置器方法以獲得最大控制權。因此,我們可以將 null 值設置為所需的值。另一方面,在設置器方法中,也可以將 null 值設置為空字符串。 此外,我們還可以使用 @JsonSetter 在字段聲明上,簡單地忽略 null 值。

這四種方法都可能適用於不同的用例。 最重要的考慮因素是如何讓應用程序處理具有 null 值的屬性。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.