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:-
MapauthPayload = 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() { MapauthPayload = 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:-
MapjsonBodyUsingMap = 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() { MapjsonBodyUsingMap = 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.
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
Thanks it was simple to understand. thank you for covering even the nested java objects