3

I'm using Jackson with Jersey in an JAX-RS environment and refer to an external library, to which I only have limited influence. From this external library I use some dataholder/-model as return type and this has an isEmpty() method comparable to String.isEmpty()

While serialization is not a problem, the deserialization causes following exception, because the datamodel does not have an setEmpty() method and Jackson interprets the isEmpty() method as field named empty.

Unrecognized field "empty" (class de.unirostock.sems.cbarchive.meta.omex.VCard), not marked as ignorable (4 known properties: "givenName", "organization", "email", "familyName"])
at [Source: org.glassfish.jersey.message.internal.EntityInputStream@36082d97; line: 1, column: 369]

It is not an option to add @JsonIgnore to the external library, because that would cause a huge overhead, also I would prefer to not capsulate the dataholder into another one and just delegate the methods or the filter the field in JavaScript.

Is there any other possibility to force Jackson to ignore this empty "field"?

FreakyBytes
  • 151
  • 1
  • 9
  • Also see [this](http://wiki.fasterxml.com/JacksonHowToIgnoreUnknown), [this](http://stackoverflow.com/questions/14343477/how-do-you-globally-set-jackson-to-ignore-unknown-properties-within-spring), and [this](http://stackoverflow.com/questions/5455014/ignoring-new-fields-on-json-objects-using-jackson). – superEb Aug 07 '14 at 16:12

2 Answers2

3

You could use Jackson's MixIn Annotations. It allows you to override default Class configuration. With this way, you can use @JsonIgnore without modifying the external library you're using.

In your exemple : You have this third party class de.unirostock.sems.cbarchive.meta.omex.VCard and you want Jackson to ignore th empty property.

Declare a MixIn class or interface :

public interface VCardMixIn {
    @JsonIgnore
    boolean isEmpty();
}

Then in your Jackson's ObjectMapper configuration :

objectMapper.getDeserializationConfig().addMixInAnnotations(VCard.class, VCardMixIn.class)
Matt
  • 3,422
  • 1
  • 23
  • 28
  • 1
    Good answer. Could also use `@JsonIgnoreProperties(ignoreUnknown=true)` on the mixin type. – superEb Aug 07 '14 at 16:05
  • thanks for your reply! MixIn types are looking exactly like the think I'm looking for, but by using Jersey in a not-Spring environment I don't know how to modify/access the Jackson ObjectMapper. Is it the right way to create a custom *ContextResolver* for *ObjectMapper*? – FreakyBytes Aug 07 '14 at 16:25
  • I've never used Jackson with Jersey so I wouldn't know. But I guess it's possible to access `ObjectMapper` and customize it anyway. Maybe [this link](http://jersey.576304.n2.nabble.com/Customizing-ObjectMapper-td6234597.html) can help. – Matt Aug 08 '14 at 08:02
  • Yes, I now implemented a custom ContextResolver and use MixIn Annotations. I mark this answer as valid. – FreakyBytes Aug 08 '14 at 14:20
  • This looks like a link-only answer (with a broken link). Using the name, I was able to google and get to [this post](https://github.com/FasterXML/jackson-docs/wiki/JacksonMixInAnnotations), but an ideal answer is self-contained and doesn't actually need the link to work to answer the OP's question. – mgilson Nov 01 '17 at 20:51
  • Thanks @mgilson You're right, I fixed the link and added some code to anser the question. – Matt Nov 02 '17 at 10:41
0

Assuming you're using ObjectMapper, you can configure it to globally ignore unknown properties.

ObjectMapper om = new ObjectMapper();
om.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

The following simple test illustrates this (using jackson-mapper-asl-1.9.10).

public static void main(String[] args) throws Exception {
    org.codehaus.jackson.map.ObjectMapper om = new org.codehaus.jackson.map.ObjectMapper();
    om.configure(org.codehaus.jackson.map.DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    String json = "{\"one\":\"hola mundo!\", \"empty\":\"unknown\", \"someOtherUnknown\":123}";
    IgnoreUnknownTestDto dto = om.readValue(json, IgnoreUnknownTestDto.class);
    System.out.println(json+" DESERIALIZED AS "+dto);
}

public static class IgnoreUnknownTestDto {
    private String one;
    public String getOne() {
        return one;
    }
    public void setOne(String one) {
        this.one = one;
    }
    public boolean isEmpty() {
        return one == null || one.isEmpty();
    }
    @Override
    public String toString() {
        return "one: '"+this.getOne()+"', empty: '"+this.isEmpty()+"'";
    }
}

which outputs:

{"one":"hola mundo!", "empty":"unknown", "someOtherUnknown":123} DESERIALIZED AS one: 'hola mundo!', empty: 'false'
superEb
  • 5,613
  • 35
  • 38