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



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



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

565   12  

12 ответов:

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

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

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

В зависимости от версии Джексона, которую вы используете, вам придется использовать другой импорт в текущей версии:

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

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

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

начиная с версии Джексона 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);

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

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 везде, где вам это нужно (по умолчанию этот объект mapper также будет использоваться для преобразования содержимого http).

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

Comments

    Ничего не найдено.