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

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

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

12 ответов


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

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

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

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

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

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

import org.codehaus.jackson.annotate.JsonIgnoreProperties;

кроме двух уже упомянутых механизмов 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);

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


до даты и полный ответ с 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 на Джексон документации.


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

  1. отметьте POJO, чтобы игнорировать неизвестные свойства

    @JsonIgnoreProperties(ignoreUnknown = true)
    
  2. настройте 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) 
    

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

@JsonIgnoreProperties(ignoreUnknown = true)

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

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

Так что код не будет ломаться.


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


начиная с версии Jackson 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


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

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

также был перемещен пакет функции десериализации. DeserializationConfig.FAIL_ON_UNKNOWN_PROPERTIES к DeserializationConfig.Особенность.FAIL_ON_UNKNOWN_PROPERTIES

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

@JsonIgnoreProperties(ignoreUnknown = true) хорошо сработало. У меня есть java-приложение, которое работает на tomcat с jdk 1.7.


я использую jackson-xxx 2.8.5.Зависимостей Maven, таких как:

<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>

во-первых,если вы хотите игнорировать неизвестные свойства во всем мире.вы можете настроить 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;
    }
}

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

например :

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

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


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