1. Обзор
В этом руководстве мы рассмотрим процесс отмены синхронизации с Jackson 2.x, в частности, как работать с содержимым JSON с неизвестными свойствами.
2. Разархивируйте 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. Непризнанное исключение propertyexception для неизвестных полей
Попытка отменить привязку 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. Работа с неизвестными полями на уровне класса
Мы также можем пометить отдельный класс как принимающий неизвестные поля, вместо всего Jackson 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. Распакуйте неполный JSON
Аналогично дополнительным неизвестным полям, отмена отправки неполного JSON, JSON, который не содержит всех полей в классе Java, не является проблемой с Jackson:
@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 с дополнительными неизвестными свойствами с помощью Jackson.
Это одна из наиболее распространенных настроек при работе с Jackson, поскольку нам часто приходится сопоставлять результаты JSON внешних REST API с внутренним Java-представлением сущностей API.
Оригинал статьи: https://www.baeldung.com/jackson-deserialize-json-unknown-properties