We already learnt Creating JSON Object Request Body Using Map. In this post we will learn to Create a JSON Object or Object Node ( In terms of Jackson API ) using Jackson API.
About Jackson API
Jackson API is a high performance JSON processor for Java. We can perform serialization, deserialization , reading a JSON file, writing a JSON file and a lot more things using Jackson API.
To use Jackson API, we need to add it in java project build path. You can add using Maven or download a jar file with transitive jars.
Maven Dependency
Always try to use latest dependency from Central Maven Repository. I will use below dependency at the time of writing this post.
com.fasterxml.jackson.core jackson-databind 2.11.0
Note :- When we add jackosn-databind dependency then it will automatically download transitive dependencies of same version i.e. jackson-annotations and jackson-core as well.
If you download and add jackson-databind jar to build path, do not forget to download other two transitive dependencies as well.
Class ObjectMapper
This is the most powerful class provided by Jackson API and maximum time we will use this class. As of now just know that ObjectMapper provides functionalities for reading and writing JSON. We will learn more about it as we proceed further.
We will use Class ObjectMapper to create a JSON Object or ObjectNode.
Let’s start with our familiar JSON payload which we will create using ObjectMapper.
{ "firstname": "Jim", "lastname": "Brown", "totalprice": 111, "depositpaid": true, "additionalneeds": "Breakfast", "bookingdates": { "checkin": "2021-07-01", "checkout": "2021-07-01" } }
Already I have explained that above JSON is a nested JSON Object. One JSON object is root node which holds fields like firstname, lastname, totalprice, depositpaid,additionalneeds and bookingdates where bookingdates is another JSON object.
Create a JSON Object or Object Node
To create a JSON Object using Jackson, we need to use createObjectNode() method of ObjectMapper class which returns an ObjectNode class instance. ObjectNode class has overloaded methods put(String fieldName, T fieldValue ) which takes field Name as String and values of different primitive and wrapper class types like String, Boolean etc. All field names should be unique. If you pass duplicate field name, it will not throw any error but override field values by latest. It is similar to put() method of Map in Java.
To get the created JSON Object as string, use writeValueAsString() provided by ObjectMapper class. If you want in proper JSON format, use writerWithDefaultPrettyPrinter() method for formatting.
Example Code
// Create an object to ObjectMapper ObjectMapper objectMapper = new ObjectMapper(); // Creating Node that maps to JSON Object structures in JSON content ObjectNode bookingDetails = objectMapper.createObjectNode(); // It is similar to map put method. put method is overloaded to accept different types of data // String as field value bookingDetails.put("firstname", "Jim"); bookingDetails.put("lastname", "Brown"); // integer as field value bookingDetails.put("totalprice", 111); // boolean as field value bookingDetails.put("depositpaid", true); bookingDetails.put("additionalneeds", "Breakfast"); // Duplicate field name. Will override value bookingDetails.put("additionalneeds", "Lunch"); // To print created json object String createdPlainJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(bookingDetails); System.out.println("Created plain JSON Object is : \n"+ createdPlainJsonObject);
Output :–
Created plain JSON Object is : { "firstname" : "Jim", "lastname" : "Brown", "totalprice" : 111, "depositpaid" : true, "additionalneeds" : "Lunch" }
Create a nested JSON Object or Object Node
To create a nested JSON Object or put another JSON Object as field value, we can not use put(String fieldName, JsonNode fieldValue) as it is deprecated. We use set(String fieldName, JsonNode fieldValue) or replace(String fieldName, JsonNode fieldValue)
Example Code
// Since requirement is to create a nested JSON Object ObjectNode bookingDateDetails = objectMapper.createObjectNode(); bookingDateDetails.put("checkin", "2021-07-01"); bookingDateDetails.put("checkout", "2021-07-01"); // Since 2.4 , put(String fieldName, JsonNode value) is deprecated. So use either set(String fieldName, JsonNode value) or replace(String fieldName, JsonNode value) bookingDetails.set("bookingdates", bookingDateDetails); // To get the created json object as string. Use writerWithDefaultPrettyPrinter() for proper formatting String createdNestedJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(bookingDetails); System.out.println("Created nested JSON Object is : \n"+ createdNestedJsonObject);
Output
Created nested JSON Object is : { "firstname" : "Jim", "lastname" : "Brown", "totalprice" : 111, "depositpaid" : true, "additionalneeds" : "Lunch", "bookingdates" : { "checkin" : "2021-07-01", "checkout" : "2021-07-01" } }
We will see some manipulation methods which are useful in parsing created JSON Object. We can use these methods to validate values. For example whatever booking details we passed, same should be used for booking.
Retrieve a field value from JSON Object or ObjectNode
To retrieve a field value we need to use get(String fieldName). If passed field name does not have a value or if there is no field with such name, null is returned. It returns a JsonNode. To get value in actual data types we need to use respective methods like asText() to get value as String or asBoolean() to get value as boolean. Be careful when field value is another ObjectNode.
Example Code
// We can retrieve field value by passing field name. Since it is string, use asText(). String firstName = bookingDetails.get("firstname").asText(); System.out.println("First name is : "+firstName); // We can use asText() as well but return type will be string boolean depositpaid = bookingDetails.get("depositpaid").asBoolean(); System.out.println("deposit paid is : "+depositpaid); // To retrieve value of nested ObjectNode bookingDetails.get("bookingdates").get("checkin").asText(); System.out.println("Checkin date is : "+depositpaid);
Output
First name is : Jim deposit paid is : true Checkin date is : true
Retrieve all field names from JSON Object or Object Node
To retrieve all field names from a ObjectNode, we need to use fieldNames() methods which returns an Iterator<String>. To get count of fields in an ObjectNode, we can use size() method.
Example Code
// To get all field names System.out.println("Count of fields in ObjectNode : "+ bookingDetails.size()); IteratorallFieldNames = bookingDetails.fieldNames(); System.out.println("Fields are : "); while(allFieldNames.hasNext()) { System.out.println(allFieldNames.next()); }
Output
Count of fields in ObjectNode : 6 Fields are : firstname lastname totalprice depositpaid additionalneeds bookingdates
Retrieve all field values from from JSON Object or ObjectNode
To retrieve all field values from an ObjectNode, use elements() method which returns an Iterator of JsonNode.
// To get all field values IteratorallFieldValues = bookingDetails.elements(); System.out.println("Fields values are : "); while(allFieldValues.hasNext()) { System.out.println(allFieldValues.next()); }
Output
Fields values are : "Jim" "Brown" 111 true "Lunch" {"checkin":"2021-07-01","checkout":"2021-07-01"}
Retrieve all key-value pair from JSON Object or ObjectNode
We can use fields() method to get all fields (with both names and values) of a JSON Object. It returns an Iterator<Entry<String,JsonNode>>.
// To get all key-value pair Iterator> allFieldsAndValues = bookingDetails.fields(); System.out.println("All fields and their values are : "); while(allFieldsAndValues.hasNext()) { Entry node = allFieldsAndValues.next(); System.out.println("Key is : "+node.getKey()+" and its value is : "+node.getValue()); }
Output
All fields and their values are : Key is : firstname and its value is : "Jim" Key is : lastname and its value is : "Brown" Key is : totalprice and its value is : 111 Key is : depositpaid and its value is : true Key is : additionalneeds and its value is : "Lunch" Key is : bookingdates and its value is : {"checkin":"2021-07-01","checkout":"2021-07-01"}
Remove a field from JSON Object or ObjectNode
Use remove(String fieldName) method to remove a field from ObjectNode. It will return value of the field, if such field existed; null if not.
Example Code
// To remove a field String removedFieldValue = bookingDetails.remove("firstname").asText(); System.out.println("Value of Removed field is " + removedFieldValue); String removedJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(bookingDetails); System.out.println("After removing field , JSON Object is : \n"+ removedJsonObject);
Output
Value of Removed field is Jim After removing field , JSON Object is : { "lastname" : "Brown", "totalprice" : 111, "depositpaid" : true, "additionalneeds" : "Lunch", "bookingdates" : { "checkin" : "2021-07-01", "checkout" : "2021-07-01" } }
Update a field from JSON Object or ObjectNode
We need to use put() method to update a field value if fieldValue is not another ObjectNode. If fieldValue is an ObjectNode use set() or replace() method.
Example Code
// To replace a field value, use put() method for non ObjectNode type and replace() or set() for ObjectNode bookingDetails.put("firstname", "Amod"); bookingDetails.put("firstname", "Aaditya"); String updatedJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(bookingDetails); System.out.println("After updating field , JSON Object is : \n"+ updatedJsonObject);
Output
After updating field , JSON Object is : { "lastname" : "Brown", "totalprice" : 111, "depositpaid" : true, "additionalneeds" : "Lunch", "bookingdates" : { "checkin" : "2021-07-01", "checkout" : "2021-07-01" }, "firstname" : "Aaditya" }
Complete Code
package DifferentWaysOfPassingPayloadToRequest; import java.util.Iterator; import java.util.Map.Entry; import org.testng.annotations.Test; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.node.ObjectNode; import io.restassured.RestAssured; import io.restassured.http.ContentType; public class CreateJsonObjectUsingJacksonAPI { @Test public void CreatingNestedJsonObjectTest() throws JsonProcessingException { // Create an object to ObjectMapper ObjectMapper objectMapper = new ObjectMapper(); // Creating Node that maps to JSON Object structures in JSON content ObjectNode bookingDetails = objectMapper.createObjectNode(); // It is similar to map put method. put method is overloaded to accept different types of data // String as field value bookingDetails.put("firstname", "Jim"); bookingDetails.put("lastname", "Brown"); // integer as field value bookingDetails.put("totalprice", 111); // boolean as field value bookingDetails.put("depositpaid", true); bookingDetails.put("additionalneeds", "Breakfast"); // Duplicate field name. Will override value bookingDetails.put("additionalneeds", "Lunch"); // To print created json object String createdPlainJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(bookingDetails); System.out.println("Created plain JSON Object is : \n"+ createdPlainJsonObject); // Since requirement is to create a nested JSON Object ObjectNode bookingDateDetails = objectMapper.createObjectNode(); bookingDateDetails.put("checkin", "2021-07-01"); bookingDateDetails.put("checkout", "2021-07-01"); // Since 2.4 , put(String fieldName, JsonNode value) is deprecated. So use either set(String fieldName, JsonNode value) or replace(String fieldName, JsonNode value) bookingDetails.set("bookingdates", bookingDateDetails); // To get the created json object as string. Use writerWithDefaultPrettyPrinter() for proper formatting String createdNestedJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(bookingDetails); System.out.println("Created nested JSON Object is : \n"+ createdNestedJsonObject); // We can retrieve field value by passing field name. Since it is string, use asText(). String firstName = bookingDetails.get("firstname").asText(); System.out.println("First name is : "+firstName); // We can use asText() as well but return type will be string boolean depositpaid = bookingDetails.get("depositpaid").asBoolean(); System.out.println("deposit paid is : "+depositpaid); // To retrieve value of nested ObjectNode bookingDetails.get("bookingdates").get("checkin").asText(); System.out.println("Checkin date is : "+depositpaid); // To get all field names System.out.println("Count of fields in ObjectNode : "+ bookingDetails.size()); IteratorallFieldNames = bookingDetails.fieldNames(); System.out.println("Fields are : "); while(allFieldNames.hasNext()) { System.out.println(allFieldNames.next()); } // To get all field values Iterator allFieldValues = bookingDetails.elements(); System.out.println("Fields values are : "); while(allFieldValues.hasNext()) { System.out.println(allFieldValues.next()); } // To get all key-value pair Iterator > allFieldsAndValues = bookingDetails.fields(); System.out.println("All fields and their values are : "); while(allFieldsAndValues.hasNext()) { Entry node = allFieldsAndValues.next(); System.out.println("Key is : "+node.getKey()+" and its value is : "+node.getValue()); } // To remove a field String removedFieldValue = bookingDetails.remove("firstname").asText(); System.out.println("Value of Removed field is " + removedFieldValue); String removedJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(bookingDetails); System.out.println("After removing field , JSON Object is : \n"+ removedJsonObject); // To replace a field value, use put() method for non ObjectNode type and replace() or set() for ObjectNode bookingDetails.put("firstname", "Amod"); bookingDetails.put("firstname", "Aaditya"); String updatedJsonObject = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(bookingDetails); System.out.println("After updating field , JSON Object is : \n"+ updatedJsonObject); } }
Output
Created plain JSON Object is : { "firstname" : "Jim", "lastname" : "Brown", "totalprice" : 111, "depositpaid" : true, "additionalneeds" : "Lunch" } Created nested JSON Object is : { "firstname" : "Jim", "lastname" : "Brown", "totalprice" : 111, "depositpaid" : true, "additionalneeds" : "Lunch", "bookingdates" : { "checkin" : "2021-07-01", "checkout" : "2021-07-01" } } First name is : Jim deposit paid is : true Checkin date is : true Count of fields in ObjectNode : 6 Fields are : firstname lastname totalprice depositpaid additionalneeds bookingdates Fields values are : "Jim" "Brown" 111 true "Lunch" {"checkin":"2021-07-01","checkout":"2021-07-01"} All fields and their values are : Key is : firstname and its value is : "Jim" Key is : lastname and its value is : "Brown" Key is : totalprice and its value is : 111 Key is : depositpaid and its value is : true Key is : additionalneeds and its value is : "Lunch" Key is : bookingdates and its value is : {"checkin":"2021-07-01","checkout":"2021-07-01"} Value of Removed field is Jim After removing field , JSON Object is : { "lastname" : "Brown", "totalprice" : 111, "depositpaid" : true, "additionalneeds" : "Lunch", "bookingdates" : { "checkin" : "2021-07-01", "checkout" : "2021-07-01" } } After updating field , JSON Object is : { "lastname" : "Brown", "totalprice" : 111, "depositpaid" : true, "additionalneeds" : "Lunch", "bookingdates" : { "checkin" : "2021-07-01", "checkout" : "2021-07-01" }, "firstname" : "Aaditya" }
There are many methods in ObjectNode which you can explore. We mostly use above methods in API automation. In next post we will learn to use created ObjectNode in Rest Assured.
You can download/clone 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 post here, all API manual and automation related posts here and find frequently asked Java Programs here.
Many other topics you can navigate through menu.
Awesome this can take us away from complexity of java map , thanks for this comprehensive and bigger one tutorial which covers end to end from creating to printing and updating also
and if we are removing a jsonObject what we shoudl take String ? as i dont see .asJsonNode()