This will work for you :

ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json);
Map<String, String> map = new HashMap<>();
addKeys("", root, map, new ArrayList<>());

map.entrySet()
     .forEach(System.out::println);

private void addKeys(String currentPath, JsonNode jsonNode, Map<String, String> map, List<Integer> suffix) {
    if (jsonNode.isObject()) {
        ObjectNode objectNode = (ObjectNode) jsonNode;
        Iterator<Map.Entry<String, JsonNode>> iter = objectNode.fields();
        String pathPrefix = currentPath.isEmpty() ? "" : currentPath + "-";

        while (iter.hasNext()) {
            Map.Entry<String, JsonNode> entry = iter.next();
            addKeys(pathPrefix + entry.getKey(), entry.getValue(), map, suffix);
        }
    } else if (jsonNode.isArray()) {
        ArrayNode arrayNode = (ArrayNode) jsonNode;

        for (int i = 0; i < arrayNode.size(); i++) {
            suffix.add(i + 1);
            addKeys(currentPath, arrayNode.get(i), map, suffix);

            if (i + 1 <arrayNode.size()){
                suffix.remove(arrayNode.size() - 1);
            }
        }

    } else if (jsonNode.isValueNode()) {
        if (currentPath.contains("-")) {
            for (int i = 0; i < suffix.size(); i++) {
                currentPath += "-" + suffix.get(i);
            }

            suffix = new ArrayList<>();
        }

        ValueNode valueNode = (ValueNode) jsonNode;
        map.put(currentPath, valueNode.asText());
    }
}

For the json you gave the output will be :

name-items-name-1-2=2nditem
name-items-name-1-1=firstitem
name-items-stock-1-1=12
name-first-1=John
name-items-stock-1-2=23
company=John Company
name-last-1=Doe
Answer from Daniel Taub on Stack Overflow
🌐
Readthedocs
jse.readthedocs.io › en › latest › utils › jackson › jacksonJsonNodeForEach.html
Jackson JsonNode.forEach() with Java 8 Consumer — Java Repositories 1.0 documentation
Jackson has provided JsonNode.forEach() method which will accept Java 8 consumer definition to iterate each node. The consumer accepts only super classes of JsonNode.
🌐
Baeldung
baeldung.com › home › json › jackson › working with tree model nodes in jackson
Working with Tree Model Nodes in Jackson | Baeldung
January 8, 2024 - Next, let’s look at an Array node. Each item within the Array node is itself a JsonNode, so we iterate over the Array and pass each node to the appendNodeToYaml method.
Top answer
1 of 4
30

This will work for you :

ObjectMapper mapper = new ObjectMapper();
JsonNode root = mapper.readTree(json);
Map<String, String> map = new HashMap<>();
addKeys("", root, map, new ArrayList<>());

map.entrySet()
     .forEach(System.out::println);

private void addKeys(String currentPath, JsonNode jsonNode, Map<String, String> map, List<Integer> suffix) {
    if (jsonNode.isObject()) {
        ObjectNode objectNode = (ObjectNode) jsonNode;
        Iterator<Map.Entry<String, JsonNode>> iter = objectNode.fields();
        String pathPrefix = currentPath.isEmpty() ? "" : currentPath + "-";

        while (iter.hasNext()) {
            Map.Entry<String, JsonNode> entry = iter.next();
            addKeys(pathPrefix + entry.getKey(), entry.getValue(), map, suffix);
        }
    } else if (jsonNode.isArray()) {
        ArrayNode arrayNode = (ArrayNode) jsonNode;

        for (int i = 0; i < arrayNode.size(); i++) {
            suffix.add(i + 1);
            addKeys(currentPath, arrayNode.get(i), map, suffix);

            if (i + 1 <arrayNode.size()){
                suffix.remove(arrayNode.size() - 1);
            }
        }

    } else if (jsonNode.isValueNode()) {
        if (currentPath.contains("-")) {
            for (int i = 0; i < suffix.size(); i++) {
                currentPath += "-" + suffix.get(i);
            }

            suffix = new ArrayList<>();
        }

        ValueNode valueNode = (ValueNode) jsonNode;
        map.put(currentPath, valueNode.asText());
    }
}

For the json you gave the output will be :

name-items-name-1-2=2nditem
name-items-name-1-1=firstitem
name-items-stock-1-1=12
name-first-1=John
name-items-stock-1-2=23
company=John Company
name-last-1=Doe
2 of 4
24

elements() gives you an iterator for subnodes and fields() gives you the properties.

With that, you can code a recursive function that walks through all nodes.

🌐
Jenkov
jenkov.com › tutorials › java-json › jackson-jsonnode.html
Jackson JsonNode
The JsonNode class has a method named fieldNames() which returns an Iterator that enables you to iterate all the field names of the JsonNode. You can use the field names to get the field values.
🌐
Tabnine
tabnine.com › home page › code › java › com.fasterxml.jackson.databind.jsonnode
com.fasterxml.jackson.databind.JsonNode.iterator java code examples | Tabnine
" \"result\": \"test.ru\"}\n" + "}"; Iterator<JsonNode> paramsIterator = mapper.readTree(requestGood).at("/params").iterator(); List<JsonNode> paramsNodes = new ArrayList<>(); while (paramsIterator.hasNext()) {
🌐
Apps Developer Blog
appsdeveloperblog.com › home › java › java json › iterate over jsonnode in java
Iterate over JsonNode in Java - Apps Developer Blog
August 12, 2022 - Here is an example program that iterates through the fields of a JsonNode and prints the field names and values: import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import java.util.Iterator; import java.util.Map; class User { private String name; private String city; private String state; // constructors, getters, setters and toString() method } class Test { public static void main(String[] args) throws IOException { ObjectMapper objectMapper = new ObjectMapper(); String json = "{\"key1\":\"value1\",\"user\":{\"name\":\"Steve\",\"city\":\"Paris\
🌐
Tabnine
tabnine.com › home page › code › java › com.fasterxml.jackson.databind.jsonnode
com.fasterxml.jackson.databind.JsonNode.forEach java code examples | Tabnine
private HashMap<String, String> getObjectHrefs(JsonNode objectNode) { HashMap<String, String> result = new LinkedHashMap<>(); JsonNode linksNode = objectNode.get("_links"); Iterator<String> names = linksNode.fieldNames(); linksNode.forEach(node -> result.put(names.next(), node.get("href").toString().replace("\"", ""))); return result; }
Find elsewhere
🌐
Baeldung
baeldung.com › home › json › jackson › simplified array operations on jsonnode without typecasting in jackson
Simplified Array Operations on JsonNode Without Typecasting in Jackson | Baeldung
June 27, 2025 - This approach reduces the overall complexity by directly iterating through the elements. It provides a straightforward mechanism for customizing the processing of JSON elements during iteration. In this tutorial, we explored various approaches to simplifying array operations on JsonNode without explicitly typecasting it to ArrayNode in Jackson.
Top answer
1 of 3
13

You are parsing the JSON when Jackson is meant to do it for you. Don't do this to yourself.

One option is to create a DTO (Data Transfer Object) that matches the format of your JSON

class Root {
    private String message;
    private String cod;
    private int count;
    private List<City> list;
    // appropriately named getters and setters
}

class City {
    private long id;
    private String name;
    private Coordinates coord;
    private List<Weather> weather;
    // appropriately named getters and setters
}

class Coordinates {
    private double lon;
    private double lat;
    // appropriately named getters and setters
}

class Weather {
    private int id;
    private String main;
    private String description;
    private int temp;
    // appropriately named getters and setters
}

Then use an ObjectMapper and deserialize the root of the JSON.

ObjectMapper mapper = new ObjectMapper();
Root root = mapper.readValue(yourFileInputStream, Root.class);

You can then get the field you want. For example

System.out.println(root.getList().get(0).getWeather().get(0).getTemp());

prints

74

The alternative is to read your JSON in as a JsonNode and traverse it until you get the JSON element you want. For example

JsonNode node = mapper.readTree(new File("text.json"));
System.out.println(node.get("list").get(0).get("weather").get(0).get("temp").asText());

also prints

74
2 of 3
3

Based on the answer that Sotirios Delimanolis gave me, here was my solution:

ObjectMapper mapper = new ObjectMapper();
JsonFactory jfactory = mapper.getFactory();
JsonParser jParser;
try {
    jParser = jfactory.createParser( tFile );
    JsonNode node = mapper.readTree( jParser);
    int count = node.get("count").asInt();
    for ( int i = 0; i < count; i++ ) {
     System.out.print( "City: " + node.get("list").get(i).get("name").asText() );
        System.out.println( " , Absolute temperature: " + 
            node.get("list").get(i).get("main").get("temp").asText() );
    }
    jParser.close();
} catch (IOException e) {
    e.printStackTrace();
}
🌐
ConcretePage
concretepage.com › jackson-api › jackson-jsonnode-foreach-with-java-8-consumer
Jackson JsonNode.forEach() with Java 8 Consumer
March 2, 2015 - Jackson API Jackson has provided JsonNode.forEach() method which will accept Java 8 consumer definition to iterate each node. The consumer accepts only super classes of JsonNode.
🌐
Fasterxml
fasterxml.github.io › jackson-core › javadoc › 1.9 › org › codehaus › jackson › JsonNode.html
JsonNode (Jackson JSON Processor)
Iterator that can be used to traverse all key/value pairs for object nodes; empty iterator (no contents) for other types ... This method is similar to get(String), except that instead of returning null if no such value exists (due to this node not being an object, or object not having value ...
🌐
GitHub
github.com › FasterXML › jackson-databind › issues › 3120
Return `ListIterator` from `ArrayNode.elements()` · Issue #3120 · FasterXML/jackson-databind
April 16, 2021 - Iterator<Map.Entry<String, JsonNode>> fields = currentNode.fields(); while (fields.hasNext()) { Map.Entry<String, JsonNode> entry = fields.next(); entry.setValue( deriveNode(entry.getValue()) ); }
Author   ludgerb
🌐
Java Code Geeks
javacodegeeks.com › home › enterprise java
Simplified Json Array Operations with JsonNode in Jackson
May 6, 2024 - This article focuses on Simplified Array Operations on JsonNode in Jackson, providing techniques to handle JSON arrays seamlessly using Jackson’s JsonNode in Java, without the need for explicit typecasting. We’ll explore various methods like get(), createArrayNode(), and techniques involving Java’s StreamSupport and Iterator to streamline JSON array handling.
🌐
Medium
medium.com › @reham.muzzamil_67114 › a-quick-guide-to-iterate-over-a-dynamic-json-string-6b024aa6b1e
A quick guide to Iterate over a dynamic JSON string! | by Reham Muzzamil | Medium
May 16, 2020 - Following snippet traverses JsonNode using Jackson library. We have to convert JSON string into JsonNode first before traversal! A JsonNode is a generic container of elements inside a JSON stream.
🌐
Baeldung
baeldung.com › home › json › jackson › get all the keys in a json string using jsonnode
Get all the Keys in a JSON String Using JsonNode | Baeldung
May 11, 2024 - While iterating using JsonParser, we can check the token type and perform required operations. Let’s fetch all the field names for our example JSON string: public List<String> getKeysInJsonUsingJsonParser(String json, ObjectMapper mapper) throws IOException { List<String> keys = new ArrayList<>(); JsonNode jsonNode = mapper.readTree(json); JsonParser jsonParser = jsonNode.traverse(); while (!jsonParser.isClosed()) { if (jsonParser.nextToken() == JsonToken.FIELD_NAME) { keys.add((jsonParser.getCurrentName())); } } return keys; }