【问题标题】:Read part of a JSON String using Jackson使用 Jackson 读取 JSON 字符串的一部分
【发布时间】:2012-07-25 12:25:22
【问题描述】:

JSON字符串如下

{
   "rank":"-text_relevance",
   "match-expr":"(label 'star wars')",
   "hits":{
      "found":7,
      "start":0,
      "hit":[
         {"id":"tt1185834",
             "data":{
                "actor":["Abercrombie, Ian","Baker, Dee","Burton, Corey"],
                "title":["Star Wars: The Clone Wars"]
             }
         },
         .
         .
         .
         {"id":"tt0121766",
             "data":{
                "actor":["Bai, Ling","Bryant, Gene","Castle-Hughes, Keisha"],
                "title":["Star Wars: Episode III - Revenge of the Sith"]
             }
         }
       ]
    },
    "info":{
       "rid":"b7c167f6c2da6d93531b9a7b314ad030b3a74803b4b7797edb905ba5a6a08",
       "time-ms":2,
       "cpu-time-ms":0
    }
    } 

它有很多字段,但我只想要数据字段。这行不通:

mapper.readvalue(jsonString,Data.class); 

如何让 Jackson 只读取“数据”字段?

【问题讨论】:

    标签: java json jackson


    【解决方案1】:

    Jackson 2.3 现在有一个可以使用的 JsonPointer 类。在他们的quick overview 中有一个简单的例子。

    用法很简单:对于JSON之类的

    {
        "address" : { "street" : "2940 5th Ave", "zip" : 980021 },   
        "dimensions" : [ 10.0, 20.0, 15.0 ] 
    }
    

    你可以使用如下表达式:

      JsonNode root = mapper.readTree(src); 
      int zip =root.at("/address/zip").asIntValue(); 
      double height = root.add("/dimensions/1").asDoubleValue();// assuming it's the second number in there
    

    【讨论】:

    • 这里的mapper 对象是什么?对象映射器?
    【解决方案2】:

    我认为最简单的方法是使用 Jackson TreeModel:假设您了解数据结构,让 Jackson 将 JSON 输入解析为 JsonNode 对象,然后您可以查询该对象。这样您就可以忽略大部分数据,沿着JsonNodes 向下查找您想要的数据。

    // String input = The JSON data from your question
    ObjectMapper mapper = new ObjectMapper();
    
    JsonNode rootNode = mapper.readValue(input.getBytes(), JsonNode.class); 
    
    // can also use ArrayNode here, but JsonNode allows us to get(index) line an array:
    JsonNode hits = rootNode.get("hits");
    
    // can also use ObjectNodes here:
    JsonNode oneHit = null;
    JsonNode dataObj = null;
    
    int idx = 0;
    
    Data data = null;
    
    
    if (hits != null)
    {
        hits = hits.get("hit");
    
        if (hits != null)
        {
            while ((oneHit = hits.get(idx)) != null)
            {
                dataObj = oneHit.get("data");
                System.out.println("Data[" + idx + "]: " + dataObj);
                idx++;
            }
        }
    }
    

    输出:

     Data[0]: {"id":"tt1185834","data":{"actor":["Abercrombie, Ian","Baker, Dee","Burton, Corey"],"title":["Star Wars: The Clone Wars"]}}
     Data[1]: {"id":"tt0121766","data":{"actor":["Bai, Ling","Bryant, Gene","Castle-Hughes, Keisha"],"title":["Star Wars: Episode III - Revenge of the Sith"]}}
    

    您仍然可以使用您的Data 类实现,但我相信这将需要获取代表每个data 的String - 如上所述依赖toString,或使用JsonNode.getText() - 并重新解析它使用ObjectMapper:

    mapper.readValue(dataArray, Data.class));
    

    另一种方法是使用杰克逊流模型,并自己拦截节点,直到您看到标记每个 data 元素开头的输入部分,然后使用字符串并在内容上调用 objectMapper.readValue,每个字符串。

    【讨论】:

      【解决方案3】:

      Json-path 可能是满足此类要求的一个很好的替代方案 - 如果您对 Jackson 以外的解决方案感到满意,那就是:http://code.google.com/p/json-path/

      【讨论】:

        猜你喜欢
        • 2018-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-05
        • 1970-01-01
        • 2013-07-31
        • 2021-01-08
        相关资源
        最近更新 更多