我试图使用Jackson api从Json中删除一个文本节点,但下面是错误:
com.fasterxml.jackson.databind.node.TextNode cannot be cast to com.fasterxml.jackson.databind.node.ObjectNode
不知道我哪里搞错了。
ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readValue(jsonText, JsonNode.class);
for (JsonNode node : json) {
if (node.isNull() || node.isBoolean() || node.isNumber() || node.isTextual()) {
((ObjectNode) node).removeAll();
}
}
我明白了为什么我要到这里来,我试图把原语转换成对象,如何从Json删除一个原语节点,在这里我需要做什么。
发布于 2020-08-25 13:37:44
这里的问题不在于原语与对象之间的关系,而是因为ObjectNode
表示一个JSON对象-即一个{...}
结构,而一个TextNode
代表一段JSON文本"foo"
。您不能在表示这些不同JSON结构的不同Java对象之间进行转换。
要删除JSON结构的部分,我建议使用迭代器。
假设我们有一些测试数据:
{
"count": 123,
"active": true,
"message": "hello world",
"details": {
"firstName": "John",
"lastName": "Smith"
}
}
我将在以下代码示例中将其作为字符串处理:
String jsonText = "{\"count\":123,\"active\":true,\"message\":\"hello world\",\"details\":{\"firstName\":\"John\",\"lastName\":\"Smith\"}}";
System.out.println(jsonText);
ObjectMapper mapper = new ObjectMapper();
JsonNode json = mapper.readValue(jsonText, JsonNode.class);
Iterator<JsonNode> it = json.iterator();
while (it.hasNext()) {
JsonNode node = it.next();
if (node.isNull() || node.isBoolean() || node.isNumber() || node.isTextual()) {
it.remove();
}
}
String outputText = mapper.writeValueAsString(json);
System.out.println(outputText);
这方面的产出如下:
{"count":123,"active":true,"message":"hello world","details":{"firstName":"John","lastName":"Smith"}}
{"details":{"firstName":"John","lastName":"Smith"}}
所有文本、布尔值和数字字段都已被删除--只有“详细信息”对象{...}
未被删除。如果测试输入包含一个数组[...]
,那么它也会被保留下来。
请注意,此解决方案仅在JSON测试数据中的顶级节点上迭代。它不对"details“数组中的子节点进行迭代。如果要深入研究JSON的层次结构,则需要修改方法--例如,递归调用方法:
private JsonNode removeUnwantedNodes(JsonNode json) {
Iterator<JsonNode> it = json.iterator();
while (it.hasNext()) {
JsonNode node = it.next();
if (node.isNull() || node.isBoolean() || node.isNumber() || node.isTextual()) {
it.remove();
} else if (node.isContainerNode()) {
removeUnwantedNodes(node);
}
}
return json;
}
在本例中,isContainerNode()
方法检查JSON对象{...}
和JSON数组[...]
。
更新-空容器
删除文本/布尔/数字节点的一个后果是,您可以在JSON中以空容器结束:{}
和[]
。
您可能需要一个或多个后续的通行证来删除这些。
检查的条件是:
if (node.isContainerNode() && node.isEmpty()) {
it.remove();
}
这可以添加到上面所示的方法中。
我处理这件事的方式如下:
(a)在迭代JSON之前创建JSON的深层副本(用于节点删除)。使用JsonNode prevJson = json.deepCopy();
制作副本。
(b)使用while
循环反复遍历JSON,并将得到的JSON与前面的副本进行比较:
while (!json.equals(prevJson)) {
prevJson = json.deepCopy();
json = iterateForRemoval(json);
}
一旦移除过程找不到需要移除的任何内容,您就完成了。
这是清理嵌套数组和对象所必需的:[ [ [...] ] ]
,其中第一次传递只能清理最内部的数组,随后的传递将删除结果中的空数组。
https://stackoverflow.com/questions/63579097
复制相似问题