Custom JSON field deserialization using Jackson

I am using Jackson to deserialize some JSON and I ran into some problems when trying to use my own deserializer for one of the fields.

class MyClass
{
    private static class SpecialPropertyDeserializer extends JsonDeserializer<SpecialProperty>
    {
        @Override
        public SpecialProperty deserialize(JsonParser jsonParser,
                                           DeserializationContext deserializationContext) throws IOException, JsonProcessingException
        {
            // do some custom deserialisation
        }
    }

    private static class SpecialProperty
    {
        private String m_foo;

        private String m_bar;

        @JsonCreator
        SpecialProperty(@JsonProperty("foo") String foo,
                        @JsonProperty("bar") String bar)
        {
            m_foo = foo;
            m_bar = bar;
        }
    }

    private String m_identifier;

    private String m_version;

    @JsonDeserialize(using = SpecialPropertyDeseializer.class)
    private SpecialProperty m_specialProperty;

    @JsonCreator
    MyClass(@JsonProperty("identifier") String identifier,
            @JsonProperty("version") String version,
            @JsonProperty("specialProperty") SpecialProperty specialProperty)
    {
        m_identifier = identifier;
        m_version = version;
        m_specialProperty = specialProperty;
    }
}

      

and this is JSON, I want to deserialize:

{
    "identifier" : "some-id",
    "version"    : "1.7",
    "specialProperty"    : {
        "foo" : "str1",
        "bar" : "str2"
    },
}

      

I call the cartographer like this:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);   
return objectMapper.readValue(input, MyClass.class);

      

I've observed the following behavior:

  • Without a special property, everything works fine - i.e. removes all references to SpecialProperty

    from code and JSON.
  • If I have included SpecialProperty

    in JSON but removed the custom deserializer for it then it works fine too. Ctor for SpecialProperty

    .
  • It doesn't work with a custom deserializer. The ctor is called for SpecialProperty

    , but the custom deserializer is not.

What am I doing wrong?

+3


source to share


1 answer


@JsonDeserialize

annotation can be placed in field, setter or class. Jackson will take this into account if what is being annotated is used to set a value.

Eg1. It notices @JsonDeserialize

above the installer if it uses the installer to set the field value.

Eg2 It notices @JsonDeserialize

above a field if it directly sets that field without using a setter or constructor.

It will tend to take this into account if it is of a class, unless overridden by a more specific annotation on the field or setter docs.I believe the docs might be clearer on the above details.

In your case, you have an annotation on a field SpecialProperty

, but you set that field in the constructor MyClass

to be ignored.



In this case, you can move @JsonDeserialize

on top of the class instead of the field. This is probably the simplest solution in your case. For example.

@JsonDeserialize(using = MyClass.SpecialPropertyDeserializer.class)
private static class SpecialProperty {

      

Or you can skip the annotation altogether and register the deserializer on the crankcase. Make SpecialProperty

and SpecialPropertyDeserializer

not private in first MyClass

, and then:

ObjectMapper objectMapper = new ObjectMapper();
SimpleModule module = new SimpleModule();
module.addDeserializer(MyClass.SpecialProperty.class, new MyClass.SpecialPropertyDeserializer());
objectMapper.registerModule(module);

      

You can also get rid of the constructor MyClass

and the current field annotation SpecialProperty

will be taken into account.

+1


source







All Articles