从LinkedHashMap中检索值

时间:2015-12-03 22:44:51

标签: java json jackson

我有一个看起来像这样的对象:

{
/test1: {
  get: {
   tags: [
     "restcalls"
   ]
 }
},
/test2: {
  put: {
   tags: [
     "restcalls"
   ]
 }
}
}

我正在检索上面这样的对象:

HashMap<?, ?> json = new ObjectMapper().readValue(str, HashMap.class);

但是,检索tags并将其替换为其他关键字的最佳方法是"my rest calls"。请注意,get,put也可以是任何其他变量名,所以它的动态但标签总是在get,put。

2 个答案:

答案 0 :(得分:3)

您已选择Jackson作为您的Java-JSON库(我可以说是一个不错的选择),因此您手头的问题是如何使用Jackson遍历和更新JSON的最佳方式,但是那些甚至决定使用哪个Java-JSON库的人可以阅读here,它比较了下面提到的7个Java-JSON库。以下是链接摘录摘录:

  

作为结论,如果您知道您将仅使用小   您的应用程序中的数据量,您希望存储或读取它   从JSON格式,你应该考虑使用Flexjson或Gson 。如果   您将使用大量数据并希望存储或阅读   它与JSON格式相比,你应该考虑使用Jackson或者   JSON-LIB

  • 杰克逊
  • 谷歌-GSON
  • JS​​ON-LIB
  • Flexjson
  • JS​​ON-IO
  • genson
  • JSONiJ

<小时/>

杰克逊

最重要的是要了解Jackson提供了三种处理JSON的替代方法(阅读更多here),因此应根据具体要求明智地选择合适的方法。

  1. Streaming API 又名&#34;增量解析/生成&#34; ):它读写JSON内容作为离散事件。 最佳用例:迭代事件(或令牌)流。 类似于: SAX和Stax

  2. 树模型: 它提供了JSON文档的可变内存树表示。树模型类似于XML DOM。 最佳用例:将Json数据绑定到Java对象中。 类似于: JAXB

  3. 数据绑定: 它根据属性访问器约定或注释将JSON转换为POJO和从POJO转换。有两种变体:简单和完整数据绑定。 最佳案例使用:构建树结构(来自Json)并使用合适的方法遍历它。 类似于: DOM

    • 简单数据绑定意味着与Java地图,列表,字符串,数字,布尔值和空值进行转换
    • 完整数据绑定意味着转换为任何Java bean类型(以及上面提到的&#34;简单&#34;类型)
  4. 通常使用&#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

    树模型优势:

    阅读here了解更多详情

    • 如果Json内容的结构高度不规则,则可能很难(或不可能)找到或创建等效的Java对象结构。树模型可能是唯一的实用选择。
    • 用于显示任何JSON内容。 树模型是内部访问和操作的自然选择。
    • 由于我们不需要绑定特定的Java对象,因此可能需要编写更少的代码。

    进一步阅读:

    <小时/> 根据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);
        }
    }
}