web-dev-qa-db-fra.com

Jackson JSON: récupère le nom du noeud depuis json-tree

Comment puis-je recevoir les noms de nœud depuis une arborescence JSON à l'aide de Jackson? Le fichier JSON ressemble à ceci:

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

J'ai

JsonNode rootNode = mapper.readTree(fileReader);

et besoin de quelque chose comme 

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

merci.

41
Oskar Alfons

Cette réponse s’applique aux versions de Jackson antérieures à 2+ (initialement écrites pour 1.8). Voir @ La réponse de SupunSameera pour une version qui fonctionne avec les versions les plus récentes de Jackson.


Les termes JSON pour "nom du noeud" est "clé". Puisque JsonNode#iterator() N'inclut pas les clés, vous devez itérer différemment :

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

Si vous seulement avez besoin de voir les touches, vous pouvez simplifier un peu les choses avec JsonNode#fieldNames() :

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

Et si vous voulez juste trouver le noeud avec la clé "foo", vous pouvez y accéder directement . Cela donnera de meilleures performances (recherche à temps constant) et un code plus propre/plus clair qu'avec une boucle:

JsonNode foo = rootNode.get("foo");
if (foo != null)
{
    // frob that widget
}
57
Matt Ball

Pour Jackson 2+ (com.fasterxml.jackson), les méthodes sont légèrement différentes:

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());
}
60
Supun Sameera

les champs () et fieldNames () ne fonctionnaient pas tous les deux pour moi. Et j'ai dû passer pas mal de temps à trouver un moyen de parcourir les clés. Il y a deux façons de le faire.

On est en le convertissant en une carte (prend plus de place):

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

Un autre, en utilisant un itérateur de chaîne:

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

Clarification ici:

Alors que cela fonctionnera:

 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())
 }

Cela ne va pas:

JsonNode rootNode = objectMapper.readTree(file);

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

Veillez donc à déclarer la Iterator en tant que variable et à l'utiliser.

Veillez à utiliser la bibliothèque fasterxml au lieu de codehaus.

5
ChrisGeo
JsonNode root = mapper.readTree(json);
root.at("/some-node").fields().forEachRemaining(e -> {
                              System.out.println(e.getKey()+"---"+ e.getValue());

        });

En une ligne Jackson 2+

0
nash