Introduction
We may get a nested JSON Object which may be dynamic. The dynamic response may include conditional keys and values. For example- A business class ticket will have more benefits than an economy class ticket. If we have an API that books a ticket then obviously we will have different JSON (Suppose JSON as format) response. The same may apply for the JSON request body as well.
In short, you may need to get all keys from a normal JSON object and nested JSON object. This is an interview question as well. You may be asked just to check the presence of a key in JSON response.
Prerequisite
Required Java Library
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
Simple JSON Object
Example JSON Object
{ "firstName": "Animesh", "lastName": "Prashant" }
Using Java MAP
As we know that we can deserialize a JSON Object to Java Map easily. As Map is a key-value pair we can get all keys easily.
package JacksonTutorials; import java.util.Map; import java.util.Set; import org.testng.annotations.Test; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; public class GetAllKeysFromJsonObject { @Test public void getAllKeysFromJsonObjectUsingMap() throws JsonMappingException, JsonProcessingException { String jsonObject = "{\r\n" + " \"firstName\": \"Animesh\",\r\n" + " \"lastName\": \"Prashant\"\r\n" + "}"; ObjectMapper objectMapper = new ObjectMapper(); // Deserializing into a Map MapparsedJsonObject = objectMapper.readValue(jsonObject, new TypeReference
Output
All keys are : firstName lastName
Using JsonNode
We need to use a method “readTree()” provided by “ObjectMapper” class which is overloaded. Method “readTree()” is to deserialize JSON content as tree expressed using a set of JsonNode instances. JsonNode is a base class for all JSON nodes, which form the basis of the JSON Tree Model that Jackson implements. One way to think of these nodes is to consider them similar to DOM nodes in XML DOM trees. Source – Jackson Java Doc
package JacksonTutorials; import java.util.Iterator; 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 GetAllKeysFromJsonObject { @Test public void getAllKeysFromJsonObjectUsingObjectMapper() throws JsonMappingException, JsonProcessingException { String jsonObject = "{\r\n" + " \"firstName\": \"Animesh\",\r\n" + " \"lastName\": \"Prashant\"\r\n" + "}"; ObjectMapper objectMapper = new ObjectMapper(); // Converting JSON Object string to JsonNode JsonNode parsedJsonObject = objectMapper.readTree(jsonObject); // Get all fields or keys IteratorallKeys= parsedJsonObject.fieldNames(); System.out.println("All keys are : "); allKeys.forEachRemaining(k -> System.out.println(k)); } }
Output
All keys are : firstName lastName
Nested JSON Object
Example JSON Object
{ "firstName": "Animesh", "lastName": "Prashant", "address": { "city": "Katihar", "State": "Bihar" } }
If we use the above logic to get keys from the nested JSON object we will not get keys “city” and “state”. So here we need to put extra logic to check if the value of a key is a JSON Object. If yes then we need to get keys from that as well.
Using Map
When we deserialize a JSON Objects to Map then it is actually an instance of LinkedHashMap. We can use LinkedHashMap directly instead of Map.
package JacksonTutorials; import java.util.LinkedHashMap; import java.util.Map; import java.util.Set; import org.testng.annotations.Test; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; public class GetAllKeysFromJsonObject { @Test public void getAllKeysFromNestedJsonObjectUsingMap() throws JsonMappingException, JsonProcessingException { String jsonObject = "{\r\n" + " \"firstName\": \"Animesh\",\r\n" + " \"lastName\": \"Prashant\",\r\n" + " \"address\": {\r\n" + " \"city\": \"Katihar\",\r\n" + " \"State\": \"Bihar\"\r\n" + " }\r\n" + "}"; ObjectMapper objectMapper = new ObjectMapper(); // Deserialize into Map MapparsedJsonObject = objectMapper.readValue(jsonObject, new TypeReference
Output
firstName lastName city State
Using JsonNode
package JacksonTutorials; import java.util.Iterator; 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; import com.fasterxml.jackson.databind.node.ObjectNode; import com.fasterxml.jackson.databind.node.TextNode; public class GetAllKeysFromJsonObject { @Test public void getAllKeysFromNestedJsonObjectUsingJsonNode() throws JsonMappingException, JsonProcessingException { String jsonObject = "{\r\n" + " \"firstName\": \"Animesh\",\r\n" + " \"lastName\": \"Prashant\",\r\n" + " \"address\": {\r\n" + " \"city\": \"Katihar\",\r\n" + " \"State\": \"Bihar\"\r\n" + " }\r\n" + "}"; ObjectMapper objectMapper = new ObjectMapper(); JsonNode parsedJsonObject = objectMapper.readTree(jsonObject); IteratorallKeys= parsedJsonObject.fieldNames(); allKeys.forEachRemaining(k -> { Object value = parsedJsonObject.get(k); // TextNode can be related to String from previous example // You may need to add IntNode or BooleanNode for different types of values if(value instanceof TextNode) System.out.println(k); // ObjectNode can be related to LinkedHashMap from previous example else if(value instanceof ObjectNode) { Iterator keyss = ((ObjectNode)value).fieldNames(); keyss.forEachRemaining(ke -> System.out.println(ke)); } }); } }
Output
firstName lastName city State
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.