java2890
java2890

Reputation: 211

ignoring unknown fields on JSON objects using jackson

I am using jackson 2.x for serialization and deserialization. I am registered the objectMapper to the afterBurner module and configured the object mapper to ignore unknown properties

objectMapper.registerModule(new AfterBurnerModule());
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

but when it is trying to serialize an object it is failing with unknown field found for attribute error

The java object is also annotated with @JsonIgnoreProperties(ignoreUnknown = true)

Can some one help me understand what might be going wrong

Below is the Util class

package example;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.AnnotationIntrospector;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector;
import com.fasterxml.jackson.module.afterburner.AfterburnerModule;
import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector;

public final class Util {
    private static ObjectMapper objectMapper;

    static {
        objectMapper = new ObjectMapper();
        objectMapper.registerModule(new AfterburnerModule());
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");
        objectMapper.setDateFormat(sdf);
        objectMapper.setAnnotationIntrospector(AnnotationIntrospector.pair(new JaxbAnnotationIntrospector(objectMapper.getTypeFactory()), new JacksonAnnotationIntrospector()));
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        objectMapper.setSerializationInclusion(Include.NON_NULL);

    }

    private Util() {
    }

    public static <T> T convertToObject(String jsonString,Class<T> classType){
        T obj = null;
        try {
            obj = objectMapper.readValue(jsonString, classType);
        } catch (Exception e) {

        } 
        return obj;
    }

    public static String convertToString(Object obj)
            throws IOException {
        return objectMapper.writeValueAsString(obj);
    }

}

enum class NumberEnum

package sample;

public enum NumberEnum {
ONE, TWO
}

class A

package sample;

@JsonIgnoreProperties(ignoreUnknown = true)
public class A {
@JsonProperty
    private NumberEnum number;
}

the code where i am deserializing is as below

A a = Util.convertToObject(str, A.class);

and the string i am trying to deserailize is as below:

{
  "number": "Num"
}

Below is the error while deserializing:

com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not construct instance of sample.NumberEnum from String value 'Num': value not one of declared Enum instance names: [ONE, TWO] at (through reference chain: sample.A["a"]->sample.NumberEnum["number"])

the class A is imported from a jar and it is using jackson library 1.9

Upvotes: 5

Views: 27453

Answers (2)

NW0428
NW0428

Reputation: 146

I think what you need to deserialize is actually json that looks like this: { "number": "ONE" }

- OR -

{ "number": "TWO" }

since "Num" is not a the name() of either of your enums it will not deserialize

Upvotes: 1

Mark Peters
Mark Peters

Reputation: 81054

ignoreUnknown only applies to property names that are unknown in the destination object. For example, if you had:

{
  "number": "ONE",
  "foo": "bar"  
}

Jackson would normally fail if the object you're trying to deserialize had no setter/property named "foo".

What you're trying to accomplish is entirely different; the property is known, but you're trying to handle an invalid enum value. If you just want it to deserialize unknown values as null, use READ_UNKNOWN_ENUM_VALUES_AS_NULL:

Feature that allows unknown Enum values to be parsed as null values. If disabled, unknown Enum values will throw exceptions. (...) Feature is disabled by default.

This is done via mapper configuration:

objectMapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true);

Note: I just saw that you're using Jackson 1.9, and this deserialization feature was released in 2.0. If upgrading is not an option, you might need to create a custom deserializer for this property which does the same thing.

Upvotes: 9

Related Questions