未知のプロパティを持つJackson非整列化JSON

1概要

この記事では、Jackson 2.xの非整列化プロセス、具体的には 不明なプロパティを持つJSONの扱い方 を見ていきます。

あなたがもっと深く掘り下げて あなたがジャクソン2 ですることができる** 他のクールなことを学びたいなら - メインのジャクソンチュートリアル に向かって進んでください。

2追加/未知のフィールドを持つJSONを非整列化する

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

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

public class MyDto {

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

    public MyDto() {
        super();
    }

   //standard getters and setters and not included
}

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を追加の未知のプロパティーでデシリアライズする方法について説明しました。

これは、外部のREST APIのJSONをAPIのエンティティの内部Java表現に** マッピングすることが多いため、Jacksonで作業するときに設定する最も一般的なものの1つです。

これらすべての例とコードスニペットの実装はhttps://github.com/eugenp/tutorials/tree/master/jackson#readme[my GitHubプロジェクト]にあります。** - これはMavenベースのプロジェクトなので、インポートしてそのまま実行するのは簡単なはずです。