Jackson - Unmarshall to Collection/Array

Jackson - Unmarshall to Collection / Array

1. Vue d'ensemble

Ce tutoriel montrera commentdeserialize a JSON Array to a Java Array or Collection with Jackson 2.

Si vous voulez creuser plus profondément et apprendreother cool things you can do with the Jackson 2 - allez àthe main Jackson tutorial.

2. Unmarshall à Array

Jackson peut facilement se désérialiser sur un tableau Java:

@Test
public void givenJsonArray_whenDeserializingAsArray_thenCorrect()
  throws JsonParseException, JsonMappingException, IOException {

    ObjectMapper mapper = new ObjectMapper();
    List 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. Unmarshall à la collection

La lecture du même tableau JSON dans une collection Java est un peu plus difficile - par défaut,Jackson will not be able to get the full generic type information et créera à la place une collection d'instances liéesHashMap:

@Test
public void givenJsonArray_whenDeserializingAsListWithNoTypeInfo_thenNotCorrect()
  throws JsonParseException, JsonMappingException, IOException {

    ObjectMapper mapper = new ObjectMapper();

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

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

Il y a deux façons dehelp Jackson understand the right type information - nous pouvons soit utiliser lesTypeReference fournis par la bibliothèque à cette fin:

@Test
public void givenJsonArray_whenDeserializingAsListWithTypeReferenceHelp_thenCorrect()
  throws JsonParseException, JsonMappingException, IOException {

    ObjectMapper mapper = new ObjectMapper();

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

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

Ou nous pouvons utiliser la méthode surchargéereadValue qui accepte unJavaType:

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

    List 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 asList = mapper.readValue(jsonArray, javaType);

    assertThat(asList.get(0), instanceOf(MyDto.class));
}

Une dernière remarque est que la classeMyDto doit avoir le constructeur par défaut no-args - si ce n’est pas le cas,Jackson will not be able to instantiate it:

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

4. Conclusion

Le mappage de tableaux JSON avec des collections java est l'une des tâches les plus courantes pour lesquelles Jackson est utilisé, et ces solutionsare vital to getting to a correct, type-safe mapping.

L'implémentation de tous ces exemples et extraits de codecan be found in our GitHub project - il s'agit d'un projet basé sur Maven, il devrait donc être facile à importer et à exécuter tel quel.