Игнорирование новых полей объектов JSON с использованием Jackson

Я использую библиотеку Jackson JSON для преобразования некоторых объектов JSON в классы POJO в приложении Android. Проблема в том, что объекты JSON могут меняться и добавлять новые поля при публикации приложения, но в настоящее время они будут разбиты даже при добавлении простого поля String, которое можно смело игнорировать.

Есть ли способ сказать Джексону игнорировать новые поля? (например, несуществующие объекты POJO)? Глобальное игнорирование было бы замечательным.

Ответ 1

Джексон предоставляет аннотацию, которая может использоваться на уровне класса (JsonIgnoreProperties).

Добавьте следующее в начало своего класса (а не к отдельным методам):

@JsonIgnoreProperties(ignoreUnknown = true)
public class Foo {
    ...
}

В зависимости от используемой вами версии jackson вам придется использовать другой импорт в текущей версии:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

в старых версиях он был:

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

Ответ 2

В дополнение к 2 уже упомянутым механизмам, существует также глобальная функция, которая может использоваться для подавления всех сбоев, вызванных неизвестными (не отображенными) свойствами:

// jackson 1.9 and before
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// or jackson 2.0
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Это значение по умолчанию, используемое при отсутствии аннотаций, и может быть удобным откатом.

Ответ 3

Обновленный и полный ответ с Jackson 2


Использование аннотации

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class MyMappingClass {

}

См. JsonIgnoreProperties в онлайн-документации Джексона.

Использование конфигурации

Менее интрузивный, чем аннотация.

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

ObjectReader objectReader = objectMapper.reader(MyMappingClass.class);
MyMappingClass myMappingClass = objectReader.readValue(json);

См. FAIL_ON_UNKNOWN_PROPERTIES в онлайн-документации Джексона.

Ответ 4

это может быть достигнуто двумя способами:

  • Отметьте POJO для игнорирования неизвестных свойств

    @JsonIgnoreProperties(ignoreUnknown = true)
    
  • Настройте ObjectMapper, который сериализует/де-сериализует POJO/json, как показано ниже:

    ObjectMapper mapper =new ObjectMapper();            
    // for Jackson version 1.X        
    mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // for Jackson version 2.X
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 
    

Ответ 5

Если используется класс pojo на основе ответа JSON. Если есть вероятность, что изменения json часто объявляются на уровне класса pojo:

@JsonIgnoreProperties(ignoreUnknown = true)

и в объектеMapper добавьте это, если вы конвертируете:

objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Так что этот код не сломается.

Ответ 6

@JsonIgnoreProperties(ignoreUnknown = true) работал хорошо для меня. У меня есть Java-приложение, которое работает на Tomcat с JDK 1,7.

Ответ 7

Начиная с версии Джексона 2.4 и выше, произошли некоторые изменения. Вот как вы это делаете сейчас:

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;

..........................................................................

 ObjectMapper mapper = new ObjectMapper();
    // to prevent exception when encountering unknown property:
 mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

Примечание. Решение на основе @annotation остается таким же, поэтому, если вы хотите использовать это, см. другие ответы.

For more information see the 10 minutes Configuration tutorial at: https://github.com/FasterXML/jackson-databind

Ответ 8

Убедитесь, что вы помещаете аннотацию @JsonIgnoreProperties(ignoreUnknown = true) в родительский класс POJO, который вы хотите заполнить в результате разбора ответа JSON, а не класса, в котором происходит преобразование из JSON в объект Java.

Ответ 9

Как указано выше, аннотации выполняются только в том случае, если это указано в родительском классе POJO, а не в классе, в котором происходит преобразование из JSON в объект Java.

Другая альтернатива, не касаясь родительского класса и вызывающая сбои, заключается в том, чтобы реализовать свой собственный конфигуратор mapper только для методов сопоставления, которые вам нужны для этого.

Также был перемещен пакет функции десериализации. DeserializationConfig.FAIL_ON_UNKNOWN_PROPERTIES to DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES

import org.codehaus.jackson.map.DeserializationConfig;
...
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Ответ 10

Для тех, кто использует Spring Boot, вы можете настроить поведение Джексона по умолчанию с помощью Jackson2ObjectMapperBuilder.

Например:

@Bean
public Jackson2ObjectMapperBuilder configureObjectMapper() {
    Jackson2ObjectMapperBuilder oMapper = new Jackson2ObjectMapperBuilder();
    oMapper.failOnUnknownProperties(false);
    return oMapper;
}

Затем вы можете автоматически подключать ObjectMapper везде, где вам это нужно (по умолчанию этот объектный преобразователь также будет использоваться для преобразования содержимого http).

Ответ 11

Я использую jackson-xxx 2.8.5.Maven Dependency как:

<dependencies>
    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-core</artifactId>
        <version>2.8.5</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-annotations</artifactId>
        <version>2.8.5</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.8.5</version>
    </dependency>

</dependencies>

Во-первых, если вы хотите игнорировать неизвестные свойства globally.you можете config ObjectMapper.
Как ниже:

ObjectMapper objectMapper = new ObjectMapper();

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Если вы хотите игнорировать некоторый класс, вы можете добавить аннотацию @JsonIgnoreProperties(ignoreUnknown = true) в свой класс, например:

@JsonIgnoreProperties(ignoreUnknown = true)
public class E1 {

    private String t1;

    public String getT1() {
        return t1;
    }

    public void setT1(String t1) {
        this.t1 = t1;
    }
}

Ответ 12

Вы можете аннотировать конкретное свойство в своем POJO с помощью @JsonIgnore.