序列化 Jackson JSON 树模型时排除 NullNode

Sha*_*aun 5 java json jackson

我有一个 pojo 类型,它需要在序列化时将特定数值设置为特殊字符串。这些值将始终为空,可能非常深入层次结构。

为了实现这一点,我首先将 pojo 转换为具有完整空值的 JsonNode 以保留属性顺序,然后我遵循结构中的路径来设置一些字符串并根据需要创建节点。最后,我让 ObjectMapper 将 JsonNode 序列化为字符串。逻辑看起来像这样:

ObjectMapper nonNullMapper = new ObjectMapper();
nonNullMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

ObjectMapper includeAllMapper = new ObjectMapper();
includeAllMapper.setSerializationInclusion(JsonInclude.Include.ALWAYS);

// NullNodes create stubs to maintain property order
JsonNode node = includeAllMapper.valueToTree(pojoInstance);
insertStrings(node);

String json = nonNullMapper.writeValueAsString(node); 
// Halp, there's still nulls
Run Code Online (Sandbox Code Playgroud)

请注意,我知道有一个 @JsonInclude注释,所以我实际上并不需要两个映射器,但事实证明我想在其他地方序列化没有空值的 pojo 实例,所以我无法使用它。

无论如何,如何避免将 NullNodes 序列化到我的 json 字符串中?到目前为止,我发现了两种方法:

  1. 转换为 Map,然后序列化为 String,使用 SerializationFeature.WRITE_NULL_MAP_VALUES禁用。这似乎效率低下且笨拙。
  2. 在序列化 JsonNode 之前手动删除 NullNode 实例。鉴于支持排除 pojo 和地图的空值,似乎没有必要,并且它增加了(也许?)不必要的复杂性。

我尝试注册一个JsonSerializerfor NullNode,但它似乎没有被使用。我注意到它NullNode本身实现了JsonSerializable,它只是委托给SerializerProvider的空值序列化器。我犹豫要不要覆盖它,我觉得应该在序列化值之前进行空过滤,但我没有深入了解它是如何工作的。

有没有更好的办法?

Nei*_*eil 7

在@StaxMan 的回答之后,这里有一些代码来修剪 NullNodes:

public static void stripNulls(JsonNode node) {
    Iterator<JsonNode> it = node.iterator();
    while (it.hasNext()) {
        JsonNode child = it.next();
        if (child.isNull())
            it.remove();
        else
            stripNulls(child);
    }
}
Run Code Online (Sandbox Code Playgroud)


Sta*_*Man 2

我不知道有什么好的解决方案,但只是想指出 JSON 树模型 ( JsonNode) 用于呈现精确的 JSON 结构;因此,很少应用用于过滤或转换的通用特征。它非常接近所见即所得。

因此,我可能宁愿直接遍历 Tree 并NullNode明确地修剪。尝试配置 Jackson 本身来执行此操作最终比显式删除节点需要更多工作。