Автор оригинала: Eugen Paraschiv.
1. Обзор
В этой статье мы рассмотрим процесс удаления ошибок с помощью Jackson 2.x – в частности, в как работать с содержимым JSON с неизвестными свойствами .
Если вы хотите копнуть глубже и узнать другие интересные вещи, которые вы можете сделать с Джексоном – перейдите к главному учебнику Джексона .
Дальнейшее чтение:
Джексон JSON Учебник
Джексон Игнорирует свойства при сортировке
Джексон – Изменить имя поля
2. Unmarshal JSON С Дополнительными/Неизвестными Полями
Входные данные JSON бывают всех форм и размеров, и в большинстве случаев нам нужно сопоставить их с предопределенными объектами Java с заданным количеством полей. Цель состоит в том, чтобы просто игнорировать любые свойства JSON, которые не могут быть сопоставлены с существующим полем Java .
Например, предположим, что нам нужно разобрать JSON на следующую сущность Java:
public class MyDto { private String stringValue; private int intValue; private boolean booleanValue; // standard constructor, getters and setters }
2.1. Исключение UnrecognizedPropertyException для неизвестных полей
Попытка отменить привязку JSON с неизвестными свойствами к этой простой сущности Java приведет к исключению com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException :
@Test(expected = UnrecognizedPropertyException.class) public void givenJsonHasUnknownValues_whenDeserializing_thenException() throws JsonParseException, JsonMappingException, IOException { String jsonAsString = "{"stringValue":"a"," + ""intValue":1," + ""booleanValue":true," + ""stringValue2":"something"}"; ObjectMapper mapper = new ObjectMapper(); MyDto readValue = mapper.readValue(jsonAsString, MyDto.class); assertNotNull(readValue); }
Это произойдет со следующим исключением:
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "stringValue2" (class org.baeldung.jackson.ignore.MyDto), not marked as ignorable (3 known properties: "stringValue", "booleanValue", "intValue"])
2.2. Работа С Неизвестными полями С помощью ObjectMapper
Теперь мы можем настроить полный ObjectMapper игнорировать неизвестные свойства в JSON:
new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
Затем мы должны быть в состоянии прочитать этот тип JSON в предопределенную сущность Java:
@Test public void givenJsonHasUnknownValuesButJacksonIsIgnoringUnknowns_whenDeserializing_thenCorrect() throws JsonParseException, JsonMappingException, IOException { String jsonAsString = "{"stringValue":"a"," + ""intValue":1," + ""booleanValue":true," + ""stringValue2":"something"}"; ObjectMapper mapper = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); MyDto readValue = mapper.readValue(jsonAsString, MyDto.class); assertNotNull(readValue); assertThat(readValue.getStringValue(), equalTo("a")); assertThat(readValue.isBooleanValue(), equalTo(true)); assertThat(readValue.getIntValue(), equalTo(1)); }
2.3. Работа с Неизвестными полями на уровне Класса
Мы также можем пометить один класс как принимающий неизвестные поля , а не весь класс ObjectMapper :
@JsonIgnoreProperties(ignoreUnknown = true) public class MyDtoIgnoreUnknown { ... }
Теперь мы должны иметь возможность протестировать то же поведение, что и раньше – неизвестные поля просто игнорируются, и отображаются только известные поля:
@Test public void givenJsonHasUnknownValuesButIgnoredOnClass_whenDeserializing_thenCorrect() throws JsonParseException, JsonMappingException, IOException { String jsonAsString = "{"stringValue":"a"," + ""intValue":1," + ""booleanValue":true," + ""stringValue2":"something"}"; ObjectMapper mapper = new ObjectMapper(); MyDtoIgnoreUnknown readValue = mapper .readValue(jsonAsString, MyDtoIgnoreUnknown.class); assertNotNull(readValue); assertThat(readValue.getStringValue(), equalTo("a")); assertThat(readValue.isBooleanValue(), equalTo(true)); assertThat(readValue.getIntValue(), equalTo(1)); }
3. Unmarshall неполный JSON
Подобно дополнительным неизвестным полям, удаление неполного JSON – JSON, который не содержит всех полей в классе Java, – не является проблемой для Джексона:
@Test public void givenNotAllFieldsHaveValuesInJson_whenDeserializingAJsonToAClass_thenCorrect() throws JsonParseException, JsonMappingException, IOException { String jsonAsString = "{"stringValue":"a","booleanValue":true}"; ObjectMapper mapper = new ObjectMapper(); MyDto readValue = mapper.readValue(jsonAsString, MyDto.class); assertNotNull(readValue); assertThat(readValue.getStringValue(), equalTo("a")); assertThat(readValue.isBooleanValue(), equalTo(true)); }
4. Заключение
В этой статье рассматривалась десериализация JSON с дополнительными неизвестными свойствами с использованием Джексона.
Это одна из наиболее распространенных вещей для настройки при работе с Джексоном, так как часто нам нужно сопоставить результаты JSON внешних API REST с внутренним представлением Java сущностей API.
Реализацию всех этих примеров и фрагментов кода можно найти в моем проекте GitHub .