1. 概要

このチュートリアルでは、JSON配列をJackson2を使用してJava配列またはコレクションに逆シリアル化する方法を示します。

より深く掘り下げてジャクソン2でできる他のクールなことを学びたい場合は、メインのジャクソンチュートリアルに進んでください。

2. アレイへのアンマーシャル

JacksonはJava配列に簡単に逆シリアル化できます。

@Test
public void givenJsonArray_whenDeserializingAsArray_thenCorrect() 
  throws JsonParseException, JsonMappingException, IOException {
 
    ObjectMapper mapper = new ObjectMapper();
    List<MyDto> listOfDtos = Lists.newArrayList(
      new MyDto("a", 1, true), new MyDto("bc", 3, false));
    String jsonArray = mapper.writeValueAsString(listOfDtos);
 
    // [{"stringValue":"a","intValue":1,"booleanValue":true},
    // {"stringValue":"bc","intValue":3,"booleanValue":false}]

    MyDto[] asArray = mapper.readValue(jsonArray, MyDto[].class);
    assertThat(asArray[0], instanceOf(MyDto.class));
}

3. コレクションへのアンマーシャル

同じJSON配列をJavaコレクションに読み込むのは少し難しいです。デフォルトでは、 Jacksonは完全な汎用型情報を取得できず、代わりにLinkedHashMapのコレクションを作成します。インスタンス:

@Test
public void givenJsonArray_whenDeserializingAsListWithNoTypeInfo_thenNotCorrect() 
  throws JsonParseException, JsonMappingException, IOException {
 
    ObjectMapper mapper = new ObjectMapper();

    List<MyDto> listOfDtos = Lists.newArrayList(
      new MyDto("a", 1, true), new MyDto("bc", 3, false));
    String jsonArray = mapper.writeValueAsString(listOfDtos);

    List<MyDto> asList = mapper.readValue(jsonArray, List.class);
    assertThat((Object) asList.get(0), instanceOf(LinkedHashMap.class));
}

ジャクソンが正しい型情報を理解するのを助ける2つの方法があります–この目的のためにライブラリによって提供されるTypeReferenceを使用することができます。

@Test
public void givenJsonArray_whenDeserializingAsListWithTypeReferenceHelp_thenCorrect() 
  throws JsonParseException, JsonMappingException, IOException {
 
    ObjectMapper mapper = new ObjectMapper();

    List<MyDto> listOfDtos = Lists.newArrayList(
      new MyDto("a", 1, true), new MyDto("bc", 3, false));
    String jsonArray = mapper.writeValueAsString(listOfDtos);

    List<MyDto> asList = mapper.readValue(
      jsonArray, new TypeReference<List<MyDto>>() { });
    assertThat(asList.get(0), instanceOf(MyDto.class));
}

または、JavaTypeを受け入れるオーバーロードされたreadValueメソッドを使用できます。

@Test
public void givenJsonArray_whenDeserializingAsListWithJavaTypeHelp_thenCorrect() 
  throws JsonParseException, JsonMappingException, IOException {
    ObjectMapper mapper = new ObjectMapper();

    List<MyDto> listOfDtos = Lists.newArrayList(
      new MyDto("a", 1, true), new MyDto("bc", 3, false));
    String jsonArray = mapper.writeValueAsString(listOfDtos);

    CollectionType javaType = mapper.getTypeFactory()
      .constructCollectionType(List.class, MyDto.class);
    List<MyDto> asList = mapper.readValue(jsonArray, javaType);
 
    assertThat(asList.get(0), instanceOf(MyDto.class));
}

最後の注意点として、 MyDto クラスには引数なしのデフォルトコンストラクタが必要です。そうでない場合、Jacksonはそれをインスタンス化できません

com.fasterxml.jackson.databind.JsonMappingException: 
No suitable constructor found for type [simple type, class org.baeldung.jackson.ignore.MyDto]: 
can not instantiate from JSON object (need to add/enable type information?)

4. 結論

JSON配列をJavaコレクションにマッピングすることは、Jacksonが使用される最も一般的なタスクの1つであり、これらのソリューションは、正しいタイプセーフなマッピングを実現するために不可欠です。

これらすべての例とコードスニペットの実装は、GitHubプロジェクトにあります。これはMavenベースのプロジェクトであるため、そのままインポートして実行するのは簡単です。