Рубрики
Без рубрики

Джексон Разомкнул JSON с неизвестными свойствами

Как удалить JSON, содержащий неизвестные свойства, с помощью Jackson.

Автор оригинала: 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 .