REST Assured Tutorial 47 – Fetch Value From Nested JSON Array Using JsonNode – Jackson – At() Method

Introduction

As a part of End to End REST Assured Tutorial, in this post, we will parse a JSON Array as JsonNode to fetch values of different types.

Creating POJO classes for parsing a JSON to fetch values may not be easy all the time especially when you have lengthy nested JSON and dynamic JSON. Instead, we can use the tree structure of a JSON so that we can navigate to any node via a path.

Prerequisite

We have already covered parsing a simple JSON Object, Nested JSON Object and simple JSON Array as JsonNode previously. You must refer those posts to understand parsing nested JSON array well.

Fetch Value From JSON Object Using JsonNode

Fetch Value From Nested JSON Object Using JsonNode

Fetch Value From JSON Array Using JsonNode

Since we are using Jackson API of Java for this example, make sure you have the latest dependency of Jackson Databind in your project classpath. I have used below Jackson dependency for this post:-



    com.fasterxml.jackson.core
    jackson-databind
    2.11.2

Tree representation of JSON Array

Example JSON Array

Tree representation of JSON Array

You can use this site to view the tree representation of a JSON Array. A tree representation of the above example JSON array will look as below:-

A JSON array may be a collection of JSON objects or JSON arrays. Below is also a valid example of a JSON array.

[
  [
    {
      "firstName": "Amod",
      "lastName": "Mahajan",
      "age": 28,
      "isMarried": false,
      "salary": 23456.54
    },
    {
      "firstName": "Rahul",
      "lastName": "Arora",
      "age": 32,
      "isMarried": true,
      "salary": 33456.54
    }
  ],
  [
    {
      "firstName": "Amod",
      "lastName": "Mahajan",
      "age": 28,
      "isMarried": false,
      "salary": 23456.54
    },
    {
      "firstName": "Rahul",
      "lastName": "Arora",
      "age": 32,
      "isMarried": true,
      "salary": 33456.54
    }
  ]
]

Deserialize a JSON Array to Tree

We need to use class ObjectMapper provided by Jackson API. ObjectMapper class provides a method “readTree()” which is responsible to deserialize JSON content as tree expressed using a set of JsonNode instances.

We can get the value of a node using get() and path() methods of JsonNode class. We need to extract value with appropriate data types after using get() and path() methods.

We just need to use an index to fetch an element of an array which is the core concept of an array. We have already seen this concept in detail here.

For this post, I have taken a nested JSON Array as an example. If I need to get value of the “type” node of first JSON object from JSON array, we need to write statement as below:-

// Using get method
System.out.println(jsonTree.get(0).get("firstName").asText());
System.out.println(jsonTree.get(0).get("address").get(0).get("type").asText());

Above statement may be longer or complex if JSON object or JSON array is deeply nested. We can use at() method instead. We need to pass the path of target node similar to a file path.

System.out.println(jsonTree.at("/0/firstName").asText());
System.out.println(jsonTree.at("/0/address/0/type").asText());
System.out.println(jsonTree.at("/0/address/1/type").asText());

Above you see “0” and “1” they represent indexes. In fact, it is intelligent enough to use those numbers as index or key. If the node key is a number such as “0” or “1” etc then it will not complain. First, it will try to look for an index. If it is not a JSON array then it will look for a node key. If both are not present then only it will fail.

Example Program

package JsonNodeJackson;

import org.testng.annotations.Test;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ParseNestedJsonArrayToReadValues {
	
	@Test
	public void parseJsonArrayToReadValues() throws JsonMappingException, JsonProcessingException
	{
		String jsonArray = "[\r\n" + 
				"  {\r\n" + 
				"    \"firstName\": \"Amod\",\r\n" + 
				"    \"lastName\": \"Mahajan\",\r\n" + 
				"    \"address\": [\r\n" + 
				"      {\r\n" + 
				"        \"type\": \"Permanent\",\r\n" + 
				"        \"city\": \"Bengaluru\",\r\n" + 
				"        \"state\": \"Karnataka\"\r\n" + 
				"      },\r\n" + 
				"      {\r\n" + 
				"        \"type\": \"Communication\",\r\n" + 
				"        \"city\": \"Katihar\",\r\n" + 
				"        \"state\": \"Bihar\"\r\n" + 
				"      }\r\n" + 
				"    ]\r\n" + 
				"  },\r\n" + 
				"  {\r\n" + 
				"    \"firstName\": \"Animesh\",\r\n" + 
				"    \"lastName\": \"Prashant\",\r\n" + 
				"    \"address\": [\r\n" + 
				"      {\r\n" + 
				"        \"type\": \"Permanent\",\r\n" + 
				"        \"city\": \"Delhi\",\r\n" + 
				"        \"state\": \"Delhi\"\r\n" + 
				"      },\r\n" + 
				"      {\r\n" + 
				"        \"type\": \"Communication\",\r\n" + 
				"        \"city\": \"Indore\",\r\n" + 
				"        \"state\": \"MP\"\r\n" + 
				"      }\r\n" + 
				"    ]\r\n" + 
				"  }\r\n" + 
				"]";
		
		
		// Creating an instance of ObjectMapper class
		ObjectMapper objectMapper = new ObjectMapper();
		// Get tree representation of json
		JsonNode jsonTree = objectMapper.readTree(jsonArray);
		
		// Using get method
		System.out.println(jsonTree.get(0).get("firstName").asText());
		System.out.println(jsonTree.get(0).get("address").get(0).get("type").asText());
		
		// Using at() method
		// Printing details of first indexed node
		System.out.println(jsonTree.at("/0/firstName").asText());
		System.out.println(jsonTree.at("/0/address/0/type").asText());
		System.out.println(jsonTree.at("/0/address/1/type").asText());
		
		// Printing details of second indexed node
		System.out.println(jsonTree.at("/1/firstName").asText());
		System.out.println(jsonTree.at("/1/address/0/type").asText());
		System.out.println(jsonTree.at("/1/address/1/type").asText());
				
	}

}
Output
Amod
Permanent
Amod
Permanent
Communication
Animesh
Permanent
Communication

You can play around below JSON array which contains keys as numbers.

[
  {
    "firstName": "Amod",
    "lastName": "Mahajan",
    "address": [
      {
        "0": "Permanent",
        "1": "Bengaluru",
        "2": "Karnataka"
      },
      {
        "0": "Communication",
        "1": "Katihar",
        "2": "Bihar"
      }
    ]
  },
  {
    "firstName": "Animesh",
    "lastName": "Prashant",
    "address": [
      {
        "0": "Permanent",
        "1": "Delhi",
        "2": "Delhi"
      },
      {
        "0": "Communication",
        "1": "Indore",
        "2": "MP"
      }
    ]
  }
]

The below statements will give you the value of nodes:-

System.out.println(jsonTree.at("/0/address/0/0").asText());
System.out.println(jsonTree.at("/0/address/1/0").asText());

You can download/clone the above sample project from here.

If you have any doubt, feel free to comment below.
If you like my posts, please like, comment, share and subscribe.
#ThanksForReading
#HappyLearning

Find all Selenium related posts here, all API manual and automation related posts here, and find frequently asked Java Programs here.

Many other topics you can navigate through the menu.

Leave a Reply

Your email address will not be published. Required fields are marked *