Expand Authors Top

If you have a few years of experience in the Java ecosystem and you’d like to share that with the community, have a look at our Contribution Guidelines.

November Discount Launch 2022 – Top
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:

>> GET ACCESS NOW

November Discount Launch 2022 – TEMP TOP (NPI)
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:

>> GET ACCESS NOW

Expanded Audience – Frontegg – Security (partner)
announcement - icon User management is very complex, when implemented properly. No surprise here.

Not having to roll all of that out manually, but instead integrating a mature, fully-fledged solution - yeah, that makes a lot of sense.
That's basically what Frontegg is - User Management for your application. It's focused on making your app scalable, secure and enjoyable for your users.
From signup to authentication, it supports simple scenarios all the way to complex and custom application logic.

Have a look:

>> Elegant User Management, Tailor-made for B2B SaaS

1. Overview

This tutorial will show how to deserialize a JSON Array to a Java Array or Collection with Jackson 2.

If you want to dig deeper and learn other cool things you can do with the Jackson 2 – head on over to the main Jackson tutorial.

2. Unmarshall to Array

Jackson can easily deserialize to a Java Array:

@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. Unmarshall to Collection

Reading the same JSON Array into a Java Collection is a bit more difficult – by default, Jackson will not be able to get the full generic type information and will instead create a collection of LinkedHashMap instances:

@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));
}

There are two ways to help Jackson understand the right type information – we can either use the TypeReference provided by the library for this very purpose:

@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));
}

Or we can use the overloaded readValue method that accepts a JavaType:

@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));
}

One final note is that the MyDto class needs to have the no-args default constructor – if it doesn't, Jackson will not be able to instantiate it:

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. Conclusion

Mapping JSON arrays to java collections is one of the more common tasks that Jackson is used for, and these solutions are vital to getting to a correct, type-safe mapping.

The implementation of all these examples and code snippets can be found in our GitHub project – this is a Maven-based project, so it should be easy to import and run as it is.

November Discount Launch 2022 – Bottom
We’re finally running a Black Friday launch. All Courses are 30% off until next Friday:

>> GET ACCESS NOW

Jackson footer banner
Comments are closed on this article!