In this article, you'll learn how to add, remove, modify, and traverse JSON nodes in Jackson's tree model. In Jackson, we can use the tree model to represent the JSON data structure and perform different operations. This is especially useful when we cannot map the JSON structure directly to a Java class.

The ObjectMapper class can also be used to construct a hierarchical tree of nodes from JSON data. In the JSON tree model, each node is of type JsonNode which provides different methods to work with specific keys. From the tree model, you can access a specific node and read its value.

Dependencies

To add Jackson to your Gradle project, add the following dependency to build.gradle file:

implementation 'com.fasterxml.jackson.core:jackson-databind:2.10.0'

For Maven, include the below dependency to your pom.xml file:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.10.0</version>
</dependency>

Create a Node

There are three different ways to create a JsonNode using Jackson's ObjectMapper class.

1. Create a Node from Scratch

The simplest way to construct a new JsonNode object is by using the createObjectNode() method:

// create object mapper
ObjectMapper mapper = new ObjectMapper();

// create new node
JsonNode node = mapper.createObjectNode();

2. Create a Node from JSON String

Another way of creating a JsonNode object is parsing a JSON string by using the readValue() method from ObjectMapper, as shown below:

// JSON string
String json = "{\"id\":1,\"name\":\"John Doe\"}";

// create object mapper instance
ObjectMapper mapper = new ObjectMapper();

// convert JSON string to `JsonNode`
JsonNode node = mapper.readTree(json);

Check out Convert JSON String to JsonNode using Jackson tutorial for more details.

3. Create a Node from Java Object

Finally, the last way to create a new JsonNode is converting a Java Object by using the valueToTree() method from ObjectMapper:

// create user object
User user = new User("John Doe", "john.doe@example.com",
        new String[]{"Member", "Admin"}, true);

// create object mapper instance
ObjectMapper mapper = new ObjectMapper();

// convert user object to `JsonNode`
JsonNode node = mapper.valueToTree(user);

Check out Convert Java Object to JsonNode using Jackson tutorial for more details.

Transforming a Node

Convert Node to JSON String

You can simply call the toString() method (or toPrettyString() for pretty print JSON) to get the JSON structure as a string:

String json = node.toString();
// OR 
String prettyJson = node.toPrettyString();

Alternatively, you can use the writeValue() method to convert a node to JSON:

mapper.writeValue(destination, node);

Where destination can be a File, an OutputStream, or a Writer.

Convert Node to Java Object

The straightforward way to convert a node to Java Object is using the treeToValue() method:

User user = mapper.treeToValue(node, User.class);

The above code is equivalent to:

User user = mapper.convertValue(node, User.class);

Check out Convert Java Object to and from JSON using Jackson tutorial for more examples.

Manipulating a Node

The following section describes how to add, remove, and update JSON nodes from the tree model.

Find a Node

You can use the path() method to find a node in the tree model:

// find top-level node
JsonNode contact = node.path("contact");

// find nested node
JsonNode city = node.path("address").path("city");

// find and get node value
String name = node.path("name").asText();

Alternatively, you can also use the get() and with() methods to find nodes in the tree model.

Add a Node

A new node can be added as a child of another node as follows:

ObjectNode obj = (ObjectNode) node;

// add new node
obj.put("age", 45);

You can even create a new ObjectNode from scratch and add it as a nested child node:

ObjectNode obj = (ObjectNode) node;

// create address
ObjectNode address = mapper.createObjectNode();
address.put("city", "Lahore");
address.put("country", "Pakistan");

// add address node
obj.set("address", address);

Edit a Node

To update an existing node, you first need to convert it to ObjectNode. Afterward, you can use the put() method to change the field value, as shown below:

ObjectNode obj = (ObjectNode) node;

// change name value
obj.put("name", "Tom Lee");

Delete a Node

A node can be removed by calling the remove() method on its parent ObjectNode:

ObjectNode obj = (ObjectNode) node;

// remove id node
obj.remove("id");

Traversing JSON Object Nodes

Since the tree model has a hierarchical structure, we can easily iterate over all nodes by starting from the root node until we reach the child nodes:

try {
    // create object mapper instance
    ObjectMapper mapper = new ObjectMapper();

    // convert JSON file to `JsonNode`
    JsonNode node = mapper.readTree(Paths.get("user.json").toFile());

    // print JSON nodes
    System.out.println("Name: " + node.path("name").asText());
    System.out.println("Email: " + node.path("email").asText());
    System.out.println("Admin: " + node.path("admin").asBoolean());

    // iterate `roles` array
    System.out.println("Roles: ");
    for (JsonNode role : node.path("roles")) {
        System.out.println(role.asText());
    }

} catch (Exception ex) {
    ex.printStackTrace();
}

You should see the following output:

Name: John Doe
Email: john.doe@example.com
Admin: true
Roles: 
Member
Admin

Traversing JSON Array Nodes

Let us say we have the following JSON array stored in a file called users.json:

[
  {
    "name": "John Doe",
    "email": "john.doe@example.com",
    "roles": [
      "Member",
      "Admin"
    ],
    "admin": true
  },
  {
    "name": "Tom Lee",
    "email": "tom.lee@example.com",
    "roles": [
      "Member"
    ],
    "admin": false
  }
]

Just like JSON Object, you can also traverse the above JSON array nodes. All you need to do is just loop over all top-level nodes, as shown below:

try {
    // create object mapper instance
    ObjectMapper mapper = new ObjectMapper();

    // convert JSON file to `JsonNode`
    JsonNode nodes = mapper.readTree(Paths.get("users.json").toFile());

    // iterate over all users
    for (JsonNode node : nodes) {
        
        // print JSON nodes
        System.out.println("Name: " + node.path("name").asText());
        System.out.println("Email: " + node.path("email").asText());
        System.out.println("Admin: " + node.path("admin").asBoolean());

        // iterate `roles`
        System.out.println("Roles: ");
        for (JsonNode role : node.path("roles")) {
            System.out.println(role.asText());
        }
    }

} catch (Exception ex) {
    ex.printStackTrace();
}

For more Jackson examples, check out the How to read and write JSON using Jackson in Java tutorial.

✌️ Like this article? Follow @attacomsian on Twitter. You can also follow me on LinkedIn and DEV. Buy me a coffee (cost $3)

Need help to start a new Spring Boot or MEAN stack project? I am available for contract work. Hire me to accomplish your business goals with engineering and design. Let’s talk about your project: hi@attacomsian.com.