2011-10-04 796 views
34

如何使用Jackson從JSON樹接收節點名稱? 的JSON-文件看起來是這樣的:Jackson JSON:從json-tree獲取節點名稱

{ 
    node1:"value1", 
    node2:"value2", 
    node3:{ 
     node3.1:"value3.1", 
     node3.2:"value3.2" 
    } 
} 

JsonNode rootNode = mapper.readTree(fileReader); 

和需要像

for (JsonNode node : rootNode){ 
    if (node.getName().equals("foo"){ 
     //bar 
    } 
} 

感謝。

回答

46

此答案適用於2+之前的傑克遜版本(最初編寫爲1.8版本)。請參閱@SupunSameera's answer,該版本適用於更新版本的Jackson。


的 「節點名稱」 的JSON術語是 「關鍵」。由於JsonNode#iterator() 不包括鍵,你需要遍歷differently

for (Map.Entry<String, JsonNode> elt : rootNode.fields()) 
{ 
    if ("foo".equals(elt.getKey())) 
    { 
     // bar 
    } 
} 

如果需要看清按鍵,可以簡化事情有點與JsonNode#fieldNames()

for (String key : rootNode.fieldNames()) 
{ 
    if ("foo".equals(key)) 
    { 
     // bar 
    } 
} 

如果你只是想找到密鑰"foo"的節點,你可以access it directly。這將產生更好的性能(恆定時間查找)和清潔劑/更清晰的代碼比使用一個循環:

JsonNode foo = rootNode.get("foo"); 
if (foo != null) 
{ 
    // frob that widget 
} 
+10

看起來好像'getFields()'改成''領域在傑克遜2.0.0()。 –

+1

迭代通過字符串鍵:rootNode.fieldNames()'給我'只能遍歷數組或java.lang.Iterable'實例的錯誤。任何想法? –

+3

實際上遍歷'Map.Entry 條目:rootNode。字段()'也給了我 –

48

對於傑克遜2+(com.fasterxml.jackson),該方法是有點不同:

Iterator<Entry<String, JsonNode>> nodes = rootNode.get("foo").fields(); 

while (nodes.hasNext()) { 
    Map.Entry<String, JsonNode> entry = (Map.Entry<String, JsonNode>) nodes.next(); 

    logger.info("key --> " + entry.getKey() + " value-->" + entry.getValue()); 
} 
+0

這隻會迭代一些節點。我看到一些節點被跳過。 – Kieveli

6

fields()和fieldNames()都不適合我。而且我不得不花很長時間來找到一種方法來遍歷密鑰。有兩種方法可以完成。

一種是通過將其轉換成映射(佔用更多的空間):

ObjectMapper mapper = new ObjectMapper(); 
Map<String, Object> result = mapper.convertValue(jsonNode, Map.class); 
for (String key : result.keySet()) 
{ 
    if(key.equals(foo)) 
    { 
     //code here 
    } 
} 

另一個,通過使用一個字符串迭代:

Iterator<String> it = jsonNode.getFieldNames(); 
while (it.hasNext()) 
{ 
    String key = it.next(); 
    if (key.equals(foo)) 
    { 
     //code here 
    } 
} 
+0

這是唯一對我有用的東西,所有其他建議都是造成無限循環的原因。 – ampofila

+0

我顯示getFieldNames()應該是fieldNames()。 – Switch

1

澄清這裏:

雖然這將工作:

JsonNode rootNode = objectMapper.readTree(file); 
Iterator<Map.Entry<String, JsonNode>> fields = rootNode.fields(); 
while (fields.hasNext()) { 
    Map.Entry<String, JsonNode> entry = fields.next(); 
    log.info(entry.getKey() + ":" + entry.getValue()) 
} 

這不會:

JsonNode rootNode = objectMapper.readTree(file); 

while (rootNode.fields().hasNext()) { 
    Map.Entry<String, JsonNode> entry = rootNode.fields().next(); 
    log.info(entry.getKey() + ":" + entry.getValue()) 
} 

所以要小心申報Iterator作爲變量,並使用該