我有一个 pojo 类型,在序列化时需要将特定数值设置为特殊字符串。这些值将始终为空,可能在层次结构中很深。
为了实现这一点,我首先将 pojo 转换为 JsonNode,并保留完整的 null 以保留属性顺序,然后我按照结构的路径设置一些字符串并根据需要创建节点。最后,我让 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
请注意,我知道有一个 @JsonInclude
注释,所以我实际上不需要两个映射器,但事实证明我想在别处序列化没有空值的 pojo 实例,所以我可以'据我所知使用它。
无论如何,我怎样才能避免将 NullNodes 序列化到我的 json 字符串中?到目前为止,我发现了两种方法:
- 转换为 Map,然后序列化为 String,禁用
SerializationFeature.WRITE_NULL_MAP_VALUES
。这看起来效率低下而且很老套。 - 在序列化 JsonNode 之前手动删除 NullNode 实例。鉴于支持排除 pojo 和映射的空值,似乎没有必要这样做,而且它增加了(也许?)不必要的复杂性。
我尝试为 NullNode
注册一个 JsonSerializer
,但它似乎没有被使用。我注意到 NullNode
本身实现了 JsonSerializable
,它只是委托(delegate)给 SerializerProvider
的空值序列化程序。我对尝试覆盖它犹豫不决,我觉得应该在值序列化之前进行 null 过滤,但我没有深入挖掘以确切了解它是如何工作的。
有没有更好的办法?
最佳答案
根据@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);
}
}
关于java - 序列化 Jackson JSON 树模型时排除 NullNode,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21511484/