Ignoring new fields on JSON objects using Jackson [duplicate]
Asked Answered
S

12

752

I'm using Jackson JSON library to convert some JSON objects to POJO classes on an android application. The problem is, the JSON objects might change and have new fields added while the application is published, but currently it will break even when a simple String field is added, which can safely be ignored.

Is there any way to tell Jackson to ignore newly added fields? (e.g. non-existing on the POJO objects)? A global ignore would be great.

Selfeducated answered 28/3, 2011 at 5:26 Comment(0)
S
1036

Jackson provides an annotation that can be used on class level (JsonIgnoreProperties).

Add the following to the top of your class (not to individual methods):

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

Depending on the jackson version you are using you would have to use a different import in the current version it is:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

in older versions it has been:

import org.codehaus.jackson.annotate.JsonIgnoreProperties;
Selfeducated answered 28/3, 2011 at 6:52 Comment(9)
Over time, I'd rather go with this option more often, as it is less intrusive.Selfeducated
Trying to get this working on Jackson 2.x libs. This package is now changed to com.fasterxml.jackson.annotation.JsonIgnoreProperties and it isn't working for me. Any thoughts?Mindi
Using this lib in my gradle file:'com.fasterxml.jackson.core:jackson-annotations:2.3.2' + com.fasterxml.jackson.annotation.JsonIgnoreProperties works for me with the jackson core lib.Extended
how to do this with ObjectMapper?Acyclic
It worked using the com.fasterxml.jackson.annotation.JsonIgnoreProperties import, as suggested by @NikhilPatilSnob
Any way to do it on ObjectMapper level? I can't edit the class I am deserializing. Many people use it and they need those fields during deserialization but I don't. Those fields are known properties.Ageold
Spring Boot 1.4.1 uses the com.fasterxml.jackson.annotation package.Ayer
Can we make it ignore properties by default instead of adding annotation to every class?Deuterogamy
@Ageold as of now, we can configure ObjectMapper to not fail for unknown propertie: new ObjectMapper().configure(FAIL_ON_UNKNOWN_PROPERTIES, false); Other configurable stuffs: fasterxml.github.io/jackson-databind/javadoc/2.6/com/fasterxml/…Caddis
S
573

In addition to 2 mechanisms already mentioned, there is also global feature that can be used to suppress all failures caused by unknown (unmapped) properties:

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

This is the default used in absence of annotations, and can be convenient fallback.

Senate answered 28/3, 2011 at 17:52 Comment(6)
This approach was required for me since the target POJO had a member of a type we do not own that had its own custom deserialization (which would use "hidden" properties such as "__type" to do certain types of magic such as instantiations of polymorphic types). Thanks!Cyclometer
This is for clients to umarshall it manually!Asthmatic
Be aware that Spring >= 4.1.1 sets this to false automatically, without notice... jira.spring.io/browse/SPR-11891Deboer
why this config has no effet for me? jackson version 2.6.4 or 2.7.0Sporran
@Sporran These settings have been around for long time, so although you really should upgrade to latest patches for branch (2.6.7, 2.7.9), that's probably not reason. Most common reason is that framework you are using is not using ObjectMapper you are configuring.Senate
I beg to differ but if the fields change name, this will silently fail and we have no idea what is happening unless we check field by field. In my case, it even ignores the failure when the DTO lacks any field definition, which is very dangerous. So it will ignore the failure no matter what type is; use with caution.Paulettapaulette
M
162

Up to date and complete answer with Jackson 2


Using Annotation

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties(ignoreUnknown = true)
public class MyMappingClass {

}

See JsonIgnoreProperties on Jackson online documentation.

Using Configuration

Less intrusive than annotation.

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

See FAIL_ON_UNKNOWN_PROPERTIES on Jackson online documentation.

Myrilla answered 8/9, 2014 at 6:27 Comment(3)
this answer is very useful too in case one can't edit the MappingClass in order to add the annotationOccasion
You can also configure the ObjectReader directly with reader.without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)Cytokinesis
Upvote. But adding a link for "with di.xml". (dependency injection .xm) : #14343977Piton
G
95

it can be achieved 2 ways:

  1. Mark the POJO to ignore unknown properties

    @JsonIgnoreProperties(ignoreUnknown = true)
    
  2. Configure ObjectMapper that serializes/De-serializes the POJO/json as below:

    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) 
    
Gautier answered 17/8, 2017 at 19:37 Comment(0)
L
35

@JsonIgnoreProperties(ignoreUnknown = true) worked well for me. I have a java application which runs on tomcat with jdk 1.7.

Laporte answered 20/2, 2018 at 16:0 Comment(1)
Worked for Spring Boot app with jdk 1.8 as well (none of step #2 from this answer was needed)Ake
T
27

If using a pojo class based on JSON response. If chances are there that json changes frequently declare at pojo class level:

@JsonIgnoreProperties(ignoreUnknown = true)

and at the objectMapper add this if you are converting:

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

So that code will not break.

Teachin answered 3/12, 2015 at 17:8 Comment(0)
R
20

Starting with Jackson version 2.4 and above there have been some changes. Here is how you do it now:

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

Note: The @annotation based solution remains the same so if you like to use that see the other answers.

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

Rumney answered 6/12, 2016 at 10:28 Comment(0)
D
18

Make sure that you place the @JsonIgnoreProperties(ignoreUnknown = true) annotation to the parent POJO class which you want to populate as a result of parsing the JSON response and not the class where the conversion from JSON to Java Object is taking place.

Datestamp answered 3/4, 2013 at 7:32 Comment(2)
Any particular reason for this behavior ?Philanthropist
@tm.sauron It is logical to have the annotation for the target class because you don't know which fields are unknown at the source class.Lovelovebird
C
11

As stated above the annotations only works if this is specified in the parent POJO class and not the class where the conversion from JSON to Java Object is taking place.

The other alternative without touching the parent class and causing disruptions is to implement your own mapper config only for the mapper methods you need for this.

Also the package of the Deserialization feature has been moved. 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);
Coinage answered 26/9, 2014 at 18:49 Comment(0)
D
10

For whom are using Spring Boot, you can configure the default behaviour of Jackson by using the Jackson2ObjectMapperBuilder.

For example :

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

Then you can autowire the ObjectMapper everywhere you need it (by default, this object mapper will also be used for http content conversion).

Drambuie answered 13/9, 2018 at 12:44 Comment(0)
Z
8

I'm using jackson-xxx 2.8.5.Maven Dependency like:

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

First,If you want ignore unknown properties globally.you can config ObjectMapper.
Like below:

ObjectMapper objectMapper = new ObjectMapper();

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

If you want ignore some class,you can add annotation @JsonIgnoreProperties(ignoreUnknown = true) on your class like:

@JsonIgnoreProperties(ignoreUnknown = true)
public class E1 {

    private String t1;

    public String getT1() {
        return t1;
    }

    public void setT1(String t1) {
        this.t1 = t1;
    }
}
Zigzagger answered 20/12, 2016 at 2:57 Comment(0)
G
-1

You can annotate the specific property in your POJO with @JsonIgnore.

Gleason answered 28/3, 2011 at 14:53 Comment(3)
The situation is the other way around, e.g. converting JSON to POJO, so it is not possible to annotate the property (which does not exists on the POJO)Selfeducated
This does not answer the question, as Hadi said, there is no field to annotate in POJOHeptangular
This will actually completely abstain Jackson for (de)marshalling this property. So even if the property will appear in you model it will not be taken into 'account' when (de)marshalling via JacksonLenient

© 2022 - 2024 — McMap. All rights reserved.