使用 Jackson 反序列化:获取 Json 对象设置的字段列表

Posted

技术标签:

【中文标题】使用 Jackson 反序列化:获取 Json 对象设置的字段列表【英文标题】:deserialization with Jackson: get list of fields set by Json object 【发布时间】:2018-07-17 17:40:22 【问题描述】:

我想在用 Jackson 反序列化之后知道 Json 输入设置了哪些字段(甚至为 null),因此我可以区分空字段而不是设置为 null 的字段与 Json 中未指定的字段。

这个问题是在我的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;

示例:通过反序列化 "myField1": null 我希望得到 deserializedFields = ["myField1"],通过反序列化 我希望得到 deserializedFields = []。

我已经在custom deserializer and a BeanDeserializerModifier 中尝试过,但我仍然无法拦截 Json 对象内的字段列表(或者如果我这样做,它已经消耗了 JsonParser 并且无法反序列化)。 在最好的情况下,我还将获得已设置的 MyFooDto 字段的反射列表...

你知道我该怎么做吗?

感谢社区!

【问题讨论】:

欢迎来到***!确保您始终添加一个语言标签,在这种情况下为“java”,以在您的帖子中启用语法突出显示并吸引更多关注。 【参考方案1】:

最直接的方法是在每个 setter 中添加代码,将当前设置的变量名称添加到 List。例如。 :

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

MyFooDto 内部设置器喜欢:

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

如果有数百个这样的二传手,那将是很多工作。这种情况的替代方法是首先将 JSON 解析为树,遍历它以获取 JSON 属性名称以添加到集合中,然后将树转换为 MyFooDto。例如。 (假设您有一个 ObjectMapper mapperjson 下面是一个带有您的示例 JSON 的 String):

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);

【讨论】:

以上是关于使用 Jackson 反序列化:获取 Json 对象设置的字段列表的主要内容,如果未能解决你的问题,请参考以下文章

使用Jackson对JSON数组中存放不同对象反序列化

使用Jackson对JSON数组中存放不同对象反序列化

使用Jackson对JSON数组中存放不同对象反序列化

反序列化 null 值以使用 Jackson 枚举

spring/jackson:实现对保存JSON字符串的字段自动序列化和反序列化

json之jackson序列化反序列化探究(二)