我有一个看起来像这样的对象:
{
/test1: {
get: {
tags: [
"restcalls"
]
}
},
/test2: {
put: {
tags: [
"restcalls"
]
}
}
}
我正在检索上面这样的对象:
HashMap<?, ?> json = new ObjectMapper().readValue(str, HashMap.class);
但是,检索tags
并将其替换为其他关键字的最佳方法是"my rest calls"
。请注意,get,put也可以是任何其他变量名,所以它的动态但标签总是在get,put。
答案 0 :(得分:3)
您已选择Jackson作为您的Java-JSON库(我可以说是一个不错的选择),因此您手头的问题是如何使用Jackson遍历和更新JSON的最佳方式,但是那些甚至决定使用哪个Java-JSON库的人可以阅读here,它比较了下面提到的7个Java-JSON库。以下是链接摘录摘录:
作为结论,如果您知道您将仅使用小 您的应用程序中的数据量,您希望存储或读取它 从JSON格式,你应该考虑使用Flexjson或Gson 。如果 您将使用大量数据并希望存储或阅读 它与JSON格式相比,你应该考虑使用Jackson或者 JSON-LIB 强>
<小时/>
最重要的是要了解Jackson提供了三种处理JSON的替代方法(阅读更多here),因此应根据具体要求明智地选择合适的方法。
Streaming API (又名&#34;增量解析/生成&#34; ):它读写JSON内容作为离散事件。 最佳用例:迭代事件(或令牌)流。 类似于: SAX和Stax
树模型: 它提供了JSON文档的可变内存树表示。树模型类似于XML DOM。 最佳用例:将Json数据绑定到Java对象中。 类似于: JAXB
数据绑定: 它根据属性访问器约定或注释将JSON转换为POJO和从POJO转换。有两种变体:简单和完整数据绑定。 最佳案例使用:构建树结构(来自Json)并使用合适的方法遍历它。 类似于: DOM
通常使用&#34;树模型&#34; 方法从性能角度来看被视为最佳方式&#34;因为它具有遍历树的优点。
其他选项也有其自身的优势,例如 Streaming API具有较少的内存和CPU开销,而数据绑定使用方便,因为它提供List
和{ {1}} JSON数据的表示。然而,由于处理能力和内存如此之多,如今真正重要的是性能。
如果您的JSON数据很大,然后在树表示中分析树是否具有更宽的宽度或更长的长度。如果它有更宽的宽度,那么肯定使用&#34;树模型&#34;将具有与树处理相关的性能优势(确保您以块为单位进行映射而不是一次性完成整个)。但是如果树更长,意思是没有好的宽度但是就像一个很长的尾巴,那么考虑使用&#34; Streaming API&#34;因为在那种情况下,树木加工的优点无法得到证实。如果数据很小,那么它几乎不重要,您可以使用&#34;树模型&#34;作为默认值。
目前您正在使用&#34;数据绑定&#34;方法,但建议使用&#34;树模型&#34; ,因为你需要的只是遍历和操纵JSON。查看您提供的信息,看起来您需要将JSON转换为Java对象,以便&#34;数据绑定&#34;方法看起来不错。
杰克逊的com.fasterxml.jackson.databind.JsonNode
构成了杰克逊树模型的基础。 将Jackson的树模型视为HTML文档的DOM, DOM在树形结构中表示完整HTML文档的方式,Jackson的树模型表示树形结构中的完整JSON字符串
以下代码将帮助您使用Jackson的树模型并实现您的目标:
Map
进一步阅读:
<小时/> 根据OP的评论:
下面的代码显示了如何遍历和打印整个JSON。通过这种方式,您可以遍历整个JSON,然后访问您要查找的元素。要注意的是,您需要知道元素名称,即使您使用Stream API方法,您也应该知道要查找的元素名称,请参阅Stream API示例here
在任何情况下,您始终可以选择遍历整个JSON(如下面的示例所示)或进行特定和直接操作(如上例所示)
import java.io.IOException;
import java.util.Iterator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class Test {
public static void main(String[] args) throws JsonProcessingException, IOException {
String jsonString = "{\"test1\": {\"get\": {\"tags\": [\"restcalls1\"]}}, \"test2\": {\"put\": {\"tags\": [\"restcalls2\"] }}}";
ObjectMapper objectMapper = new ObjectMapper();
JsonNode rootNode = objectMapper.readTree(jsonString);
Iterator<JsonNode> iterator2 = rootNode.iterator();
while (iterator2.hasNext()) {
JsonNode node2 = iterator2.next().findParent("tags");
ObjectNode objectNode = (ObjectNode) node2;
objectNode.putArray("tags").add("my rest calls");
}
Iterator<JsonNode> iterator = rootNode.iterator();
while (iterator.hasNext()) {
JsonNode node2 = iterator.next();
System.out.println(node2);
}
}
}
答案 1 :(得分:0)
您可以使用Jackson的JsonNode
类来遍历整个JSON并更改标记的节点值。请参阅以下代码:
public class Tags {
public static void main(String[] args) throws Exception {
InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream("tags.json");
ObjectMapper om = new ObjectMapper();
JsonNode node = om.readTree(in);
recursiveFind(node);
System.out.println(node); //Prints {"test1":{"get":{"tags":["my rest calls"]}},"test2":{"put":{"tags":["my rest calls"]}}}
}
private static void recursiveFind(JsonNode node) {
if (!node.isObject()) {
return;
}
JsonNode tags = node.get("tags");
if (tags != null) {
ArrayNode arry = (ArrayNode) tags;
arry.removeAll();
arry.add("my rest calls");
}
Iterator<JsonNode> it = node.elements();
while (it.hasNext()) {
JsonNode jsonNode = it.next();
recursiveFind(jsonNode);
}
}
}