2016-08-03 97 views
3

讀取單個JSON場我都在我感興趣的單場相當大的JSON響應 - status如何與傑克遜

{ 
    "title": "Some title", 
    "status": "pending", 
    "data": { 
    ... 
    }, 
    "meta": { 
    ... 
    } 
} 

所有我需要做的是閱讀的JSON的status值作爲字符串的響應我寧願不必建立一個POJO來建模,因爲在我的應用程序中,我只需要將JSON存儲在特定狀態的數據庫中或丟棄它。

該應用程序已經在其他更復雜的情況下使用傑克遜,所以我寧願堅持使用該庫。到目前爲止,我發現的所有示例都嘗試將JSON映射到對象。

+0

是'「狀態」'總是第三行/秒的鍵值在響應一對? –

+0

我剛剛發佈了一個示例格式化的響應。它很可能來自API gzip壓縮,服務器展開後,在我可以訪問它的地步,它只是一個'字節[]'流,我可以爲UTF8字符串解碼 - 沒有假設可能除了它的有效的JSON上做出。 。 – ddinchev

回答

2

如果所需的字段是一個非空文本字段,在對象體積的「第一級」(即,不是任何嵌套對象)的對象足夠小以適應主內存,則可以使用一種簡單的檢索方法其值使用的方法等

public static String readField(String json, String name) throws IOException { 
    if (field != null) { 
     ObjectNode object = new ObjectMapper().readValue(json, ObjectNode.class); 
     JsonNode node = object.get(name); 
     return (node == null ? null : node.textValue()); 
    } 
    return null; 
    } 

ObjectNode是一個通用Jackson類,而不是一個POJO。如果要使用多個值,則應該緩存ObjectMapper(它甚至是線程安全的)。

使用上面的JSON響應字符串運行

System.out.println(readField(response, "status")); 

,返回

pending 

如預期。在StackOverflow中可找到類似的解決方案elsewhere

對於非常大的JSON對象(例如,存儲在文件中),的Jackson流的方法應該被使用,在其他的答案提示。

4

如果json響應不是很大,可以使用ObjectMapper.readTree將完整的json反序列化爲JsonNode並獲取其中的特定屬性。

例如:

ObjectMapper mapper = new ObjectMapper(); 
JsonNode jsonNode = mapper.readTree(json); 
JsonNode statusNode = jsonNode.get("status"); 
String statusValue = statusNode.textValue(); 

您還可以通過ObjectMapper.readValue反序列化JSON全面進入ObjectNode建議在other answer

如果json響應很大並且反序列化完整的json是一個問題,那麼您可以考慮使用Jackson Streaming API JsonParser來解析json。

下面是一個例子:

String statusValue = null; 

JsonFactory jsonFactory = new JsonFactory(); 
try (JsonParser parser = jsonFactory.createParser(json)) { 
    JsonToken startToken = parser.nextToken(); 
    while (parser.nextToken() != JsonToken.END_OBJECT) { 
     String fieldName = parser.getCurrentName(); 
     if ("status".equals(fieldName)) { 
      if (parser.nextToken() == JsonToken.VALUE_STRING) { 
       statusValue = parser.getValueAsString(); 
       break; 
      } 
     } else { 
      parser.skipChildren(); 
     } 
    } 
} 

JsonParser分解成JSON令牌的順序,你可以遍歷一個接一個。在這個例子中,JsonParser.skipChildren被用來跳過一個完整的對象或數組,這樣只有第一級的json層次被檢查。

+0

謝謝你的建議,upvoted,我實際上現在試試這個!我已經接受了另一個答案,因爲在給出我的問題上它更直接。 – ddinchev

+0

樂於助人。你可以嘗試兩種方式,並找到一個最適合你的情況。 – Wilson

+0

問題中提出的用例沒有內存問題,因此可以使用完整的反序列化方法(通過'JsonNode')。關於更大的尺寸和流媒體的好處。對問題和答案都+1。 :-) – PNS