Джексон JSON: получите node имя из json-tree
Как я могу получить имена node из дерева JSON с помощью Jackson?
JSON-File выглядит примерно так:
{
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
}
}
спасибо.
Ответы
Ответ 1
Этот ответ относится к версиям Джексона до 2+ (изначально написанный для версии 1.8). См. @SupunSameera answer для версии, которая работает с более новыми версиями Jackson.
Термины JSON для "node name" являются "ключом". Поскольку JsonNode#iterator()
не включает ключи, вам нужно выполнить итерацию по-другому:
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
}
}
И если вы просто хотите найти node с ключом "foo"
, вы можете получить доступ к нему напрямую. Это даст лучшую производительность (постоянный поиск) и более чистый/понятный код, чем использование цикла:
JsonNode foo = rootNode.get("foo");
if (foo != null)
{
// frob that widget
}
Ответ 2
Для Jackson 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());
}
Ответ 3
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
}
}
Другой, используя итератор String:
Iterator<String> it = jsonNode.getFieldNames();
while (it.hasNext())
{
String key = it.next();
if (key.equals(foo))
{
//code here
}
}
Ответ 4
Разъяснение здесь:
Пока это будет работать
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
как переменную и использовать его.
Обязательно используйте библиотеку fasterxml
а не codehaus
.
Ответ 5
JsonNode root = mapper.readTree(json);
root.at("/some-node").fields().forEachRemaining(e -> {
System.out.println(e.getKey()+"---"+ e.getValue());
});
В одной строке Джексон 2+