it-roy-ru.com

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

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

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

557
Hadi Eskandari

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

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

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

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

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

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

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
799
Hadi Eskandari

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

// 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);

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

417
StaxMan

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

108
Yves M.

это может быть достигнуто 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) 
    
74
Anamika Patel

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

@JsonIgnoreProperties(ignoreUnknown = true)

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

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

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

26
user5636084

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

19
Parul

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

17
Rushi Shah

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

17
Alboz

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

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

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

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

Я использую 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>

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

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

Например :

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

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

5
Thoomas