Добавить в корзинуПозвонить
Найти в Дзене
Уроки по программированию

Jackson – Unmarshall в коллекцию/массив

1. Обзор В этом руководстве показано, как десериализовать массив JSON в массив или коллекцию Java с помощью Jackson 2. 2. Unmarshall в массив 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. Unmarshall в коллекцию Считать тот же массив JSON в коллекцию Java немного сложнее — по умолчанию Jackson не сможет получить полную информацию об общем типе и вместо этого создаст коллекцию экзем
Оглавление

1. Обзор

В этом руководстве показано, как десериализовать массив JSON в массив или коллекцию Java с помощью Jackson 2.

2. Unmarshall в массив

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. Unmarshall в коллекцию

Считать тот же массив 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));
}

Есть два способа помочь Jackson понять правильную информацию о типе: мы можем либо использовать 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));
}

Или мы можем использовать перегруженный метод readValue , который принимает 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));
}

И последнее замечание: класс 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 — одна из наиболее распространенных задач, для которых используется Джексон, и эти решения жизненно важны для достижения правильного, типобезопасного сопоставления.