自动序列化嵌套空对象

问题描述 投票:0回答:1

我有一组结构如下的课程:

public class A implements Serializable {
    String prop1;
    String prop2;
    B prop3;
}

public class B implements Serializable {
    String nestedProp4;
    String nestedProp5;
    C nestedProp6;
}

public class C implements Serializable {
    String nestedProp7;
}

我需要序列化类 A 的实例。这是我正在使用的代码:

A obj = new A();
ObjectMapper mapper = new ObjectMapper();
JsonNode node = mapper.valueToTree(obj);

序列化的实际结果是:

{
    "prop1": null,
    "prop2": null,
    "prop3": null
}

但是,我需要结果包含属性为空值的嵌套结构,如下所示:

{
    "prop1": null,
    "prop2": null,
    "prop3": {
        "nestedProp4": null,
        "nestedProp5": null,
        "nestedProp6": {
            "nestedProp7": null
        }
    }
}

是否有一种自动方式或配置注释来实现这种序列化,而无需使用反射或设置默认值?

此外,我在这些类中有很多属性,所以我不喜欢为每个属性添加注释。允许在类顶部添加注释。

java serialization jackson
1个回答
0
投票

这不能用 Jackson 注解来涵盖,这是 java null 管理的问题。 考虑以下情况:

public class B2 extends B {
  String additionalNestedProp;
}

public static void main() {
  ObjectMapper mapper = new ObjectMapper();

  A obj1 = new A();
  System.out.println(mapper.valueToTree(obj1));

  A obj2 = new A();
  obj2.setProp3(new B());
  System.out.println(mapper.valueToTree(obj2));

  A obj3 = new A();
  obj3.setProp3(new B2);
  System.out.println(mapper.valueToTree(obj3));
}

输出将是这样的:

{
    "prop1": null,
    "prop2": null,
    "prop3": null
}
{
    "prop1": null,
    "prop2": null,
    "prop3": {
        "nestedProp4": null,
        "nestedProp5": null,
        "nestedProp6": null
    }
}
{
    "prop1": null,
    "prop2": null,
    "prop3": {
        "nestedProp4": null,
        "nestedProp5": null,
        "nestedProp6": null,
        "additionalNestedProp": null
    }
}

如果您希望映射器嵌套空对象,它将无法判断是否应该序列化为情况 2 还是情况 3,因为它使用正在反序列化的对象的实际类型来确定属性,而不是声明的类型。如果该对象是

null
,它根本无法确定类型,并且无法构造序列化对象(或者即使应该首先创建一个对象,如果
B2
有一个注释使得它序列化为字符串而不是 JSON 对象?)

本质上,在情况 2 中,

A
并不完全为空。
prop3
中的
obj2
设置为
B
类型的非空对象,然后该对象可以具有空字段。如果您想继续嵌套,则必须以某种形式使用默认的空对象,因为 Jackson 无法仅根据字段的声明类型来确定要包含哪些属性。

相关,您可以使用

@JsonInclude(value = JsonInclude.Include.NON_DEFAULT)
not序列化具有默认属性的属性对象(即,如果使用零参数构造函数创建它们将具有相同的属性)

© www.soinside.com 2019 - 2024. All rights reserved.