使用未知屬性解構JSON

Data,Jackson
Remote
1
01:10 AM · Dec 01 ,2025

1. 概述

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

要深入瞭解並學習更多我們可以使用 Jackson 做的事情,可以查看主 Jackson 教程。

2. Unmarshall a JSON With Additional/Unknown Fields

JSON input comes in all shapes and sizes, and most of the time, we need to map it to predefined Java objects with a set number of fields. The goal is to simply ignore any JSON properties that cannot be mapped to an existing Java field

For example, say we need to unmarshal JSON to the following Java entity:

public class MyDto {

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

    // standard constructor, getters and setters 
}

2.1. UnrecognizedPropertyException on Unknown Fields

Trying to unmarshal a JSON with unknown properties to this simple Java Entity will lead to a 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);
}

This will fail with the following exception:

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. Dealing With Unknown Fields Using the ObjectMapper

We can now configure the full ObjectMapper

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

We should then be able to read this kind of JSON into a predefined Java entity:

@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. Dealing With Unknown Fields at the Class Level

We can also mark a single class as accepting unknown fields

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

Now we should be able to test the same behavior as before. The unknown fields are simply ignored, and only known fields are mapped:

@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,即 JSON 中不包含 Java 類中所有字段的情況,對 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.