简体   繁体   中英

deserialization with Jackson: get list of fields set by Json object

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!

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

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 . Eg (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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM