当前位置: 首页 > 知识库问答 >
问题:

Jackson JSON序列化:当嵌套对象的所有字段都为空时,如何忽略它?

广亮
2023-03-14

我正在使用Jackson,我有一些JSON模式对象设置如下:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Person {

    String name;
    Child child = new Child();
    Sibling sibling = new Sibling();

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public Child getChild() {
        return child;
    }
    public void setChild(Child child) {
        this.child = child;
    }

    public Sibling getSibling() {
        return sibling;
    }
    public void setSibling(Sibling sibling) {
        this.sibling = sibling;
    }
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Child {

    String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Sibling {

    String name;

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

我试图忽略所有为空或空的字段,这工作正常。但我也想忽略字段全部为空或空的对象。例如:

Person person = new Person();
person.setName("John Doe");
ObjectMapper mapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(person);

生成的 JSON 字符串是 {“name”:“John Doe”,“child”:{},“sibling”:{}},但我希望它是 {“name”:“John Doe”}创建 Person 时需要初始化子级同级,所以我不想更改它。有没有办法让杰克逊使用自定义序列化程序将具有空字段的对象视为空?我已经看到了对特定类型的对象使用自定义序列化程序的示例,但我需要一个适用于任何对象的示例。

共有2个答案

李敏学
2023-03-14

对于您的情况,我认为忽略序列化程序级别的空值就足够了:

mapper.setSerializationInclusion(Include.NON_EMPTY);
mapper.setSerializationInclusion(Include.NON_NULL);
王扬
2023-03-14

您可以以一种可以说更简单的方式实现这一点,而无需为个人子项同级自定义序列化程序,而是使用 CUSTOM 包含并将字段类型作为过滤器传递。

首先,为<code>Child</code>和<code>Sibling</code>定义正确的<code>等于</code>方法。然后,要过滤等于其默认构造函数返回值的嵌套对象,请在Person中注释相关getter,如下所示:

@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = Child.class)
public Child getChild() {
    return child;
}

@JsonInclude(value = JsonInclude.Include.CUSTOM, valueFilter = Sibling.class)
public Sibling getSibling() {
    return sibling;
}

valueFilter 设置为 Child.class 上面的效果是创建一个具有默认构造函数 Child emptyChild = new Child() 的对象,然后决定另一个对象 Child 子子应该序列化检查 emptyChild.equals(child) 是否为 false

valueFilter的文档

 类似资料:
  • 我正在使用Jackson ObjectMapper序列化POJO。我在POJO中有嵌套字段。例如:序列化类 如果字符串为,则不序列化整个属性。也就是说,如果字符串为,我希望输出为: 但我得到的是作为输出。 我已经为序列化包含设置了(),但这并不能解决问题

  • 环境: jdk:17.0.1 映射:1.5.1.Final 使用默认配置,我生成了以下代码 但我想在source的所有字段都为null时返回null,如下所示 我应该如何配置它?

  • 我想在Java中反序列化包含空值的json字符串。我想将对象反序列化为对象。json字符串类似于: 当我反序列化使用 由于对象中的that,我得到一个空指针异常。我如何指示Gson忽略空值的反序列化?

  • 我想将包含另一个空值POJO的POJO序列化为JSON。 例如,给定: 连载之后,它看起来会是这样的 如果类的所有字段也为空,是否可以排除空对象?理想情况下,全局适用于每个对象,而无需编写自定义代码。

  • 如果类的所有字段也为空,是否可以排除空对象?理想情况下,全局地用于每个对象,而无需编写自定义代码。

  • 我对对象接口的jackson序列化有问题。 我有课 哪个实现 还有上课 哪个实现 上课 我要和Jackson连载Container得到结果 但事实上我得到了结果 尽管我在映射中指定了点的序列化类型(),但在嵌套对象“point”中具有属性“name”。接口点视图没有方法getName,但结果中存在点的字段“name”。 若我从类容器中的方法getMap中删除注释(),我将得到结果 现在点没有属性"