REST Assured Tutorial 23 – Creating JSON Object Request Body Using Java Map

As a part of End to End REST Assured Tutorial, in this post, We will learn:- How to create a JSON Object Payload using Map in Java.

In previous posts, you must have observed that I was hard coding the JSON request body in a string. It is not a good practice if you have the dynamic payload or want to create payload at run time or parameterized one. It is always good to create payload in such a way that you can easily maintain, manage, update, and retrieve values from it.

We can create a JSON Object using a Map in Java. You must note here that I am using the word “JSON Object”. A JSON Object is a key-value pair and can be easily created using a Java Map. A Map in Java also represents a collection of key-value pairs.

Start with a very simple JSON Object:

 
{
    "username" : "admin",
    "password" : "password123"
}
 

Observe above JSON Object. It contains two key-value pairs. “username” and “password” are two keys and “admin” and “password123” are its corresponding values.

Following the same, we need to create a Map and put the above key-value pairs as they ae\re. Since key and value both are string, we can create a generic Map. See the example below:-

Map authPayload = new HashMap();
authPayload.put("username", "admin");
authPayload.put("password", "password123");

Now you can directly pass above Map object to body() method which is overloaded to accept Object type.

Complete example:

package DifferentWaysOfPassingPayloadToRequest;

import java.util.HashMap;
import java.util.Map;

import org.testng.annotations.Test;

import io.restassured.RestAssured;
import io.restassured.http.ContentType;

public class CreatingRequestBodyUsingMap {
	
	@Test
	public void passBodyAsMap()
	{
		Map authPayload = new HashMap();
		authPayload.put("username", "admin");
		authPayload.put("password", "password123");
		
		
		//GIVEN
		RestAssured
		   .given()
			  .baseUri("https://restful-booker.herokuapp.com/auth")
			  .contentType(ContentType.JSON)
			  .body(authPayload)
			  .log()
			  .all()
		// WHEN
		   .when()
			   .post()
		// THEN
		   .then()
			   .assertThat()
			   .statusCode(200)
			   .log()
			   .all();
		
	}

}

I am using a logger just to show you the JSON body. Observe Output below. You will see the request body:-

[RemoteTestNG] detected TestNG version 7.0.0
Request method:	POST
Request URI:	https://restful-booker.herokuapp.com/auth
Proxy:			
Request params:	
Query params:	
Form params:	
Path params:	
Headers:		Accept=*/*
				Content-Type=application/json; charset=UTF-8
Cookies:		
Multiparts:		
Body:
{
    "password": "password123",
    "username": "admin"
}
HTTP/1.1 200 OK
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 27
Etag: W/"1b-CfXCADRO41immbrDETUmLRPUeGo"
Date: Mon, 24 Feb 2020 16:45:31 GMT
Via: 1.1 vegur

{
    "token": "3ce7cd012765c9f"
}
PASSED: passBodyAsMap

===============================================
    Default test
    Tests run: 1, Failures: 0, Skips: 0
===============================================


===============================================
Default suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================



Now see some complex example:-

Above we have seen a very basic JSON object body. Let’s learn little complex JSON Object request body.

{
    "firstname" : "Jim",
    "lastname" : "Brown",
    "totalprice" : 111,
    "depositpaid" : true,
    "bookingdates" : {
        "checkin" : "2018-01-01",
        "checkout" : "2019-01-01"
    },
    "additionalneeds" : "Breakfast"
}

A key in JSON Object can hold another JSON Object as well. Unlike the above example where we created generic Map as Map<String, String>, in this, we need to create a generic map as Map<String, Object> to allow a key in Map to have a JSON Object as value.

We need to create two Maps here. One will hold overall key-value pairs and another Map will hold only bookingdates key-value pairs. Refer example below:-

Map jsonBodyUsingMap = new HashMap();
jsonBodyUsingMap.put("firstname", "Jim");
jsonBodyUsingMap.put("lastname", "Brown");
jsonBodyUsingMap.put("totalprice", 111);
jsonBodyUsingMap.put("depositpaid", true);
		
Map bookingDatesMap = new HashMap<>();
bookingDatesMap.put("checkin", "2021-07-01");
bookingDatesMap.put("checkout", "2021-07-01");
		
jsonBodyUsingMap.put("bookingdates", bookingDatesMap);
jsonBodyUsingMap.put("additionalneeds", "Breakfast");

Complete Example Code:-

package DifferentWaysOfPassingPayloadToRequest;

import java.util.HashMap;
import java.util.Map;

import org.testng.annotations.Test;

import io.restassured.RestAssured;
import io.restassured.http.ContentType;

public class CreatingNestedJsonObject {
	
	@Test
	public void CreatingNestedJsonObjectTest()
	{
		Map jsonBodyUsingMap = new HashMap();
		jsonBodyUsingMap.put("firstname", "Jim");
		jsonBodyUsingMap.put("lastname", "Brown");
		jsonBodyUsingMap.put("totalprice", 111);
		jsonBodyUsingMap.put("depositpaid", true);
		
		Map bookingDatesMap = new HashMap<>();
		bookingDatesMap.put("checkin", "2021-07-01");
		bookingDatesMap.put("checkout", "2021-07-01");
		
		jsonBodyUsingMap.put("bookingdates", bookingDatesMap);
		jsonBodyUsingMap.put("additionalneeds", "Breakfast");
		
		
		//GIVEN
		RestAssured
		   .given()
			  .baseUri("https://restful-booker.herokuapp.com/booking")
			  .contentType(ContentType.JSON)
			  .body(jsonBodyUsingMap)
			  .log()
			  .all()
		// WHEN
		   .when()
			   .post()
		// THEN
		   .then()
			   .assertThat()
			   .statusCode(200)
			   .log()
			   .all();
	}

}

Output:-

[RemoteTestNG] detected TestNG version 7.0.0
Request method:	POST
Request URI:	https://restful-booker.herokuapp.com/booking
Proxy:			
Request params:	
Query params:	
Form params:	
Path params:	
Headers:		Accept=*/*
				Content-Type=application/json; charset=UTF-8
Cookies:		
Multiparts:		
Body:
{
    "firstname": "Jim",
    "additionalneeds": "Breakfast",
    "bookingdates": {
        "checkin": "2021-07-01",
        "checkout": "2021-07-01"
    },
    "totalprice": 111,
    "depositpaid": true,
    "lastname": "Brown"
}
HTTP/1.1 200 OK
Server: Cowboy
Connection: keep-alive
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
Content-Length: 195
Etag: W/"c3-a1U4h04tkfvUYEkrOJJWIFOJZWA"
Date: Mon, 24 Feb 2020 16:44:48 GMT
Via: 1.1 vegur

{
    "bookingid": 11,
    "booking": {
        "firstname": "Jim",
        "lastname": "Brown",
        "totalprice": 111,
        "depositpaid": true,
        "bookingdates": {
            "checkin": "2021-07-01",
            "checkout": "2021-07-01"
        },
        "additionalneeds": "Breakfast"
    }
}
PASSED: CreatingNestedJsonObjectTest

===============================================
    Default test
    Tests run: 1, Failures: 0, Skips: 0
===============================================


===============================================
Default suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================


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.

2 thoughts on “REST Assured Tutorial 23 – Creating JSON Object Request Body Using Java Map

  1. I am getting below console duing exeution:

    Please suggest.

    /usr/lib/jvm/java-1.8.0-openjdk-amd64/bin/java -ea -Didea.test.cyclic.buffer.size=1048576 -javaagent:/snap/intellij-idea-community/345/lib/idea_rt.jar=39899:/snap/intellij-idea-community/345/bin -Dfile.encoding=UTF-8 -classpath /snap/intellij-idea-community/345/lib/idea_rt.jar:/snap/intellij-idea-community/345/plugins/testng/lib/testng-rt.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/charsets.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/cldrdata.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/dnsns.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/icedtea-sound.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/jaccess.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/java-atk-wrapper.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/localedata.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/nashorn.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/sunec.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/ext/zipfs.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/jce.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/jfr.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/jsse.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/management-agent.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/resources.jar:/usr/lib/jvm/java-1.8.0-openjdk-amd64/jre/lib/rt.jar:/home/kavitha/IdeaProjects/Training/RestAssuredB1/target/test-classes:/home/kavitha/IdeaProjects/Training/RestAssuredB1/target/classes:/home/kavitha/.m2/repository/com/jayway/jsonpath/json-path/2.4.0/json-path-2.4.0.jar:/home/kavitha/.m2/repository/net/minidev/json-smart/2.3/json-smart-2.3.jar:/home/kavitha/.m2/repository/net/minidev/accessors-smart/1.2/accessors-smart-1.2.jar:/home/kavitha/.m2/repository/org/ow2/asm/asm/5.0.4/asm-5.0.4.jar:/home/kavitha/.m2/repository/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar:/home/kavitha/.m2/repository/com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar:/home/kavitha/.m2/repository/junit/junit/4.10/junit-4.10.jar:/home/kavitha/.m2/repository/org/hamcrest/hamcrest-core/1.1/hamcrest-core-1.1.jar:/home/kavitha/.m2/repository/io/rest-assured/rest-assured/4.4.0/rest-assured-4.4.0.jar:/home/kavitha/.m2/repository/org/codehaus/groovy/groovy/3.0.8/groovy-3.0.8.jar:/home/kavitha/.m2/repository/org/codehaus/groovy/groovy-xml/3.0.8/groovy-xml-3.0.8.jar:/home/kavitha/.m2/repository/org/apache/httpcomponents/httpclient/4.5.13/httpclient-4.5.13.jar:/home/kavitha/.m2/repository/org/apache/httpcomponents/httpcore/4.4.13/httpcore-4.4.13.jar:/home/kavitha/.m2/repository/commons-logging/commons-logging/1.2/commons-logging-1.2.jar:/home/kavitha/.m2/repository/commons-codec/commons-codec/1.11/commons-codec-1.11.jar:/home/kavitha/.m2/repository/org/apache/httpcomponents/httpmime/4.5.13/httpmime-4.5.13.jar:/home/kavitha/.m2/repository/org/hamcrest/hamcrest/2.1/hamcrest-2.1.jar:/home/kavitha/.m2/repository/org/ccil/cowan/tagsoup/tagsoup/1.2.1/tagsoup-1.2.1.jar:/home/kavitha/.m2/repository/io/rest-assured/json-path/4.4.0/json-path-4.4.0.jar:/home/kavitha/.m2/repository/org/codehaus/groovy/groovy-json/3.0.8/groovy-json-3.0.8.jar:/home/kavitha/.m2/repository/io/rest-assured/rest-assured-common/4.4.0/rest-assured-common-4.4.0.jar:/home/kavitha/.m2/repository/io/rest-assured/xml-path/4.4.0/xml-path-4.4.0.jar:/home/kavitha/.m2/repository/org/apache/commons/commons-lang3/3.11/commons-lang3-3.11.jar:/home/kavitha/.m2/repository/jakarta/xml/bind/jakarta.xml.bind-api/2.3.3/jakarta.xml.bind-api-2.3.3.jar:/home/kavitha/.m2/repository/jakarta/activation/jakarta.activation-api/1.2.2/jakarta.activation-api-1.2.2.jar:/home/kavitha/.m2/repository/com/sun/xml/bind/jaxb-impl/2.3.3/jaxb-impl-2.3.3.jar:/home/kavitha/.m2/repository/org/testng/testng/7.5/testng-7.5.jar:/home/kavitha/.m2/repository/com/google/code/findbugs/jsr305/3.0.1/jsr305-3.0.1.jar:/home/kavitha/.m2/repository/com/beust/jcommander/1.78/jcommander-1.78.jar:/home/kavitha/.m2/repository/org/webjars/jquery/3.5.1/jquery-3.5.1.jar com.intellij.rt.testng.RemoteTestNGStarter -usedefaultlisteners false -socket33763 @w@/tmp/idea_working_dirs_testng.tmp -temp /tmp/idea_testng.tmp
    SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder”.
    SLF4J: Defaulting to no-operation (NOP) logger implementation
    SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

    java.lang.IllegalStateException: Cannot serialize object because no JSON serializer found in classpath. Please put Jackson (Databind), Gson, Johnzon, or Yasson in the classpath.

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:72)
    at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:263)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:277)
    at io.restassured.internal.mapping.ObjectMapping.serialize(ObjectMapping.groovy:160)
    at io.restassured.internal.mapping.ObjectMapping$serialize.call(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:125)
    at io.restassured.internal.RequestSpecificationImpl.body(RequestSpecificationImpl.groovy:753)
    at tests.restAssuredConcepts.Sample23_CreateRequestBodyUsingMap.passBodyAsMap(Sample23_CreateRequestBodyUsingMap.java:43)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.testng.internal.invokers.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:135)
    at org.testng.internal.invokers.TestInvoker.invokeMethod(TestInvoker.java:673)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethod(TestInvoker.java:220)
    at org.testng.internal.invokers.MethodRunner.runInSequence(MethodRunner.java:50)
    at org.testng.internal.invokers.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:945)
    at org.testng.internal.invokers.TestInvoker.invokeTestMethods(TestInvoker.java:193)
    at org.testng.internal.invokers.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
    at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:128)
    at java.util.ArrayList.forEach(ArrayList.java:1259)
    at org.testng.TestRunner.privateRun(TestRunner.java:808)
    at org.testng.TestRunner.run(TestRunner.java:603)
    at org.testng.SuiteRunner.runTest(SuiteRunner.java:429)
    at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:423)
    at org.testng.SuiteRunner.privateRun(SuiteRunner.java:383)
    at org.testng.SuiteRunner.run(SuiteRunner.java:326)
    at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
    at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:95)
    at org.testng.TestNG.runSuitesSequentially(TestNG.java:1249)
    at org.testng.TestNG.runSuitesLocally(TestNG.java:1169)
    at org.testng.TestNG.runSuites(TestNG.java:1092)
    at org.testng.TestNG.run(TestNG.java:1060)
    at com.intellij.rt.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:66)
    at com.intellij.rt.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:109)

    ===============================================
    Default Suite
    Total tests run: 1, Passes: 0, Failures: 1, Skips: 0
    ===============================================

    Process finished with exit code 0

Leave a Reply

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