Джексон - Unmarshall в коллекцию/массив

Джексон - Unmarshall в коллекцию / массив

1. обзор

Из этого туториала Вы узнаете, какdeserialize a JSON Array to a Java Array or Collection with Jackson 2.

Если вы хотите копнуть глубже и изучитьother cool things you can do with the Jackson 2 - переходите кthe main Jackson tutorial.

2. Неупорядочить в массив

Джексон может легко десериализоваться в массив 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 в коллекцию

Чтение того же массива JSON в коллекцию Java немного сложнее - по умолчаниюJackson will not be able to get the full generic type information, вместо этого создается коллекция экземпляров LinkedHashMap:

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

Есть два способа получитьhelp Jackson understand the right type information - мы можем либо использоватьTypeReference, предоставленные библиотекой именно для этой цели:

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

Или мы можем использовать перегруженный методreadValue, который принимаетJavaType:

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

И последнее замечание: классMyDto должен иметь конструктор по умолчанию no-args - если его нет,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. Заключение

Сопоставление массивов JSON с коллекциями java - одна из наиболее распространенных задач, для которых используется Джексон, и эти решенияare vital to getting to a correct, type-safe mapping.

Реализация всех этих примеров и фрагментов кодаcan be found in our GitHub project - это проект на основе Maven, поэтому его должно быть легко импортировать и запускать как есть.