1. 概要

このチュートリアルでは、Jackson 2.xでのアンマーシャリングプロセス、具体的には不明なプロパティを持つJSONコンテンツを処理する方法を見ていきます。

より深く掘り下げて、ジャクソンでできる他のクールなことを学ぶために、メインのジャクソンチュートリアルをチェックすることができます。

2. 追加/不明なフィールドを含むJSONのマーシャリングを解除します

JSON入力にはさまざまな形とサイズがあり、ほとんどの場合、設定された数のフィールドを持つ事前定義されたJavaオブジェクトにJSON入力をマップする必要があります。 目標は、既存のJavaフィールドにマップできないJSONプロパティを単に無視することです。

たとえば、JSONを次のJavaエンティティにアンマーシャリングする必要があるとします。

public class MyDto {

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

    // standard constructor, getters and setters 
}

2.1. 不明なフィールドでのUnrecognizedPropertyException

不明なプロパティを持つJSONをこの単純なJavaエンティティにアンマーシャリングしようとすると、com.fasterxml.jackson.databind.exc.UnrecognizedPropertyExceptionが発生します。

@Test(expected = UnrecognizedPropertyException.class)
public void givenJsonHasUnknownValues_whenDeserializing_thenException()
  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を使用した不明なフィールドの処理

これで、JSONの不明なプロパティを無視するように完全なObjectMapperを構成できます。

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

これで、この種のJSONを事前定義されたJavaエンティティに読み込むことができるはずです。

@Test
public void givenJsonHasUnknownValuesButJacksonIsIgnoringUnknowns_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 givenJsonHasUnknownValuesButIgnoredOnClass_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を使用するときに構成する最も一般的なものの1つです。これは、外部RESTAPIのJSON結果をAPIのエンティティの内部Java表現マッピングする必要があるためです。

これらすべての例とコードスニペットの実装は、myGitHubプロジェクトにあります。