1

I would like to know after the deserialization with Jackson what fields where set by the Json input (even null), so I can than distinguish the null fields than where set on null from the one that where not specified in Json.

This question comes after my previous one about BeanDeserializerModifier.

public class Dto {
    public Collection<String> deserializedFields;
    // or even better a collection of reflection fields of the object.
}

public MyFooDto extends Dto {
    public Integer myField1;
    @PossiblySomeJacksonAnnotation (include, exclude, map on other name, special deserializer, etc...)
    public SomeDatatype myField2;
}

Example: by deserializing {"myField1": null} I would like to have deserializedFields = ["myField1"], and by deserializing {} I would like to have deserializedFields = [].

I already tried within a custom deserializer and a BeanDeserializerModifier, but still I cant intercept the list of fields inside the Json object (or if I do so it already consumates the JsonParser and it can't be deserialized then). In the best case I would also get the reflection list of the MyFooDto Fields that have been set...

Do you see how I could proceed?

Thank you Community!

Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82
Bill
  • 143
  • 1
  • 10
  • Welcome to stackoverflow! Make sure you always add a language tag, "java" in this case, to enable syntax highlighting in your post and attract more attention. – Manos Nikolaidis Feb 12 '18 at 16:24

1 Answers1

0

The most straightforward way is to add code in each setter to add the currently set variable name to a List. E.g. :

public class Dto {
    public List<String> deserializedFields = new ArrayList<>();
}

and inside MyFooDto setters like:

public void setMyField1(Integer myField1) {
    deserializedFields.add("myField1");
    this.myField1 = myField1;
}

That's a lot of work if there are hundreds of such setters. An alternative for such a case is to parse JSON into a tree first, traverse it to get JSON property names to add in a collection and then convert the tree to MyFooDto. E.g. (assuming you have a ObjectMapper mapper and json below is a String with your example JSON):

ObjectNode tree = (ObjectNode) mapper.readTree(json);
ArrayNode deserializedFields = mapper.createArrayNode();
tree.fields().forEachRemaining(e -> deserializedFields.add(e.getKey()));
tree.put("deserializedFields", deserializedFields);
MyFooDto dto = mapper.treeToValue(tree, MyFooDto.class);
Manos Nikolaidis
  • 21,608
  • 12
  • 74
  • 82