知識庫 / JSON / Jackson RSS 訂閱

Jackson 解析未知屬性的 JSON 數據

Data,Jackson
HongKong
6
10:03 PM · Dec 05 ,2025

1. 概述

本教程將探討使用 Jackson 2.x 進行反序列化的過程,特別是 如何處理具有未知屬性的 JSON 內容

要深入瞭解並學習更多關於 Jackson 的用法,您可以查看 Jackson 的主教程。

2. 解構包含附加/未知字段的 JSON 數據

JSON 輸入數據形式各異,大多數情況下,我們需要將其映射到預定義的 Java 對象,這些對象具有固定的字段數量。目標是簡單地忽略任何無法映射到現有 Java 字段的 JSON 屬性

例如,假設我們需要將 JSON 解構到以下 Java 實體:

public class MyDto {

    private String stringValue;
    private int intValue;
    private boolean booleanValue;

    // standard constructor, getters and setters 
}

2.1. 未知字段導致的 com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException

嘗試將包含未知屬性的 JSON 映射到此簡單的 Java 實體,將會導致 com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException

@Test(expected = UnrecognizedPropertyException.class)
public void givenJsonHasUnknownValues_whenDeserializingAJsonToAClass_thenExceptionIsThrown()
  throws JsonParseException, JsonMappingException, IOException {
    String jsonAsString =
        "{\"stringValue\":\"a\"," +
        "\"intValue\":1," +
        "\"booleanValue\":true," +
        "\"stringValue2\":\"something\"}";
    ObjectMapper mapper = new ObjectMapper();

    MyDto readValue = mapper.readValue(jsonAsString, MyDto.class);

    assertNotNull(readValue);
}

這將導致以下異常:

com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: 
Unrecognized field "stringValue2" (class org.baeldung.jackson.ignore.MyDto), 
not marked as ignorable (3 known properties: "stringValue", "booleanValue", "intValue"])

2.2. 使用 ObjectMapper 處理未知字段

現在,我們可以配置完整的 ObjectMapper 以忽略 JSON 中未知的屬性:

new ObjectMapper()
  .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)

我們應該能夠將這種 JSON 讀取到預定義的 Java 實體中:

@Test
public void givenJsonHasUnknownValuesButJacksonIsIgnoringUnknownFields_whenDeserializing_thenCorrect()
  throws JsonParseException, JsonMappingException, IOException {
 
    String jsonAsString =
        "{\"stringValue\":\"a\"," +
        "\"intValue\":1," +
        "\"booleanValue\":true," +
        "\"stringValue2\":\"something\"}";
    ObjectMapper mapper = new ObjectMapper()
      .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    MyDto readValue = mapper.readValue(jsonAsString, MyDto.class);

    assertNotNull(readValue);
    assertThat(readValue.getStringValue(), equalTo("a"));
    assertThat(readValue.isBooleanValue(), equalTo(true));
    assertThat(readValue.getIntValue(), equalTo(1));
}

2.3. 處理類級別未知字段

我們也可以將單個類標記為接受未知字段,而不是整個 Jackson 的 ObjectMapper

@JsonIgnoreProperties(ignoreUnknown = true)
public class MyDtoIgnoreUnknown { ... }

現在我們應該能夠測試之前相同的行為。未知的字段會被簡單地忽略,只有已知的字段才會進行映射:

@Test
public void givenJsonHasUnknownValuesButUnknownFieldsAreIgnoredOnClass_whenDeserializing_thenCorrect() 
  throws JsonParseException, JsonMappingException, IOException {
 
    String jsonAsString =
        "{\"stringValue\":\"a\"," +
        "\"intValue\":1," +
        "\"booleanValue\":true," +
        "\"stringValue2\":\"something\"}";
    ObjectMapper mapper = new ObjectMapper();

    MyDtoIgnoreUnknown readValue = mapper
      .readValue(jsonAsString, MyDtoIgnoreUnknown.class);

    assertNotNull(readValue);
    assertThat(readValue.getStringValue(), equalTo("a"));
    assertThat(readValue.isBooleanValue(), equalTo(true));
    assertThat(readValue.getIntValue(), equalTo(1));
}

3. 解讀不完整 JSON

類似於額外的未知字段,解讀不完整 JSON(即,不包含 Java 類中所有字段的 JSON)對 Jackson 來説也不是問題:

@Test
public void givenNotAllFieldsHaveValuesInJson_whenDeserializingAJsonToAClass_thenCorrect() 
  throws JsonParseException, JsonMappingException, IOException {
    String jsonAsString = "{"stringValue":"a","booleanValue":true}";
    ObjectMapper mapper = new ObjectMapper();

    MyDto readValue = mapper.readValue(jsonAsString, MyDto.class);

    assertNotNull(readValue);
    assertThat(readValue.getStringValue(), equalTo("a"));
    assertThat(readValue.isBooleanValue(), equalTo(true));
}

4. 結論

在本文中,我們討論了使用 Jackson 解序列化包含額外未知屬性的 JSON 的方法。

這在與 Jackson 協作時最常見的情況之一,因為我們經常需要將外部 REST API 的 JSON 結果映射到 API 實體內部的 Java 表示形式。

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

發佈 評論

Some HTML is okay.