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

Dav*_*Mar 6 java json jackson

我正在使用 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我试图忽略所有为空或空的字段,这很好用。但我也想忽略字段全部为空或空的对象。例如:

Person person = new Person();
person.setName("John Doe");
ObjectMapper mapper = new ObjectMapper();
String json = objectMapper.writeValueAsString(person);
Run Code Online (Sandbox Code Playgroud)

生成的 JSON 字符串是{"name":"John Doe","child":{},"sibling":{}},但我希望它是{"name":"John Doe"}. Child并且Sibling需要在Person创建时初始化,所以我不想改变它。有没有办法让杰克逊使用自定义序列化程序将具有空字段的对象视为空?我见过为特定类型的对象使用自定义序列化程序的示例,但我需要一个适用于任何对象的示例。

Man*_*dis 3

Person您可以通过一种可以说更简单的方式来实现这一点,而无需使用orChild和 的自定义序列化程序,Sibling但可以使用CUSTOM包含并将字段类型作为过滤器传递。

首先为和定义正确的equals方法。然后,要过滤等于其默认构造函数返回的嵌套对象,请像这样注释相关的 getter:ChildSiblingPerson

@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;
}
Run Code Online (Sandbox Code Playgroud)

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

valueFilter 的文档