我有一个 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 字符串中?到目前为止,我发现了两种方法:
SerializationFeature.WRITE_NULL_MAP_VALUES禁用。这似乎效率低下且笨拙。我尝试注册一个JsonSerializerfor NullNode,但它似乎没有被使用。我注意到它NullNode本身实现了JsonSerializable,它只是委托给SerializerProvider的空值序列化器。我犹豫要不要覆盖它,我觉得应该在序列化值之前进行空过滤,但我没有深入了解它是如何工作的。
有没有更好的办法?
在@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)
我不知道有什么好的解决方案,但只是想指出 JSON 树模型 ( JsonNode) 用于呈现精确的 JSON 结构;因此,很少应用用于过滤或转换的通用特征。它非常接近所见即所得。
因此,我可能宁愿直接遍历 Tree 并NullNode明确地修剪。尝试配置 Jackson 本身来执行此操作最终比显式删除节点需要更多工作。
| 归档时间: |
|
| 查看次数: |
4925 次 |
| 最近记录: |