I have a BDD automation framework setup with Selenium WebDriver and Cucumber with Java. I have configured Rest Assured and I am currently using one JSON payload which is stored in an external JSON file. I am directly reading this JSON file into byte array and then converting the same to String and sending the payload to a post request.
Till now, everything was static and hence, this was working without any issue. However, now the requirement is to send a couple of attributes with dynamic values everytime I make a post call. I know how to send a complete dynamic payload using POJOs but I am looking for a different solution where I can read the payload from the same JSON file and can send dynamic values for few required attributes. Please let me know if this is possible.
Attaching the code for reference.
File which reads the JSON file and sends the payload to post request
public class AddOrderAPIActions {
ConfigReader configReader = new ConfigReader();
Properties prop;
public AddOrderAPIActions() {
prop = configReader.init_prop();
}
//Setting up the API URI
public void setURI() {
String URI = prop.getProperty("apiURI");
RestAssured.baseURI = URI;
}
//Sending the request payload via POST method
public String sendRequestPayload() throws IOException {
//read data from local JSON file then store in byte array
byte[] b = Files.readAllBytes(Paths.get("./src/test/resources/data/addOrder.json"));
//convert byte array to string
String bdy = new String(b);
//input details with header and body
Response response = given().header("Content-type", "application/json").queryParam("api_key", prop.getProperty("apiKey")).body(bdy)
//adding post method
.when().post().then().log().all().extract().response();
JsonPath jp = response.jsonPath();
String shipmentNumber = jp.get("data.shipmentDetails[0].shipmentNumber");
System.out.println("Shipment Number is "+ shipmentNumber);
return shipmentNumber;
}
}
The JSON file with payload
[
{
"originDetails": {
"originCode": "Dynamic_Value",
"originStartTime": "",
"originEndTime": "",
"senderName": "Origin Name",
"senderContactNumber": "9999999999",
"senderAddress": "Bali, Indonesia",
"senderPincode": "201001",
"senderCity": "Delhi",
"senderCountry": "India"
},
]
Here, I want to send a dynamic value for "originCode" attribute and rest of the attributes should be sent as read from the JSON file.
Thanks in advance.
I am getting a value in Json Format and Assigned it into a String.
In Java, How can i Convert a String Value into a Data Set of Ignition. And
how do i Convert a Json Object to Data Set?
postRequest.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString());
ObjectMapper mapper = new ObjectMapper();
HttpEntity entity;
entity = new StringEntity(mapper.writeValueAsString(context), ContentType.APPLICATION_JSON);
postRequest.setEntity(entity);
CloseableHttpResponse httpResponse = null;
httpResponse = httpClient.execute(postRequest);
String response = null;
response = EntityUtils.toString(httpResponse.getEntity());
AnalysisData = response;
Dataset dataset = Dataset.class.cast(vAnalysisData);
Java does not handle Json parsing on it's own. You must import a third party Json library. Google Gson is the one I use. Here is the link. Once the Json response is parsed into Json Elements, then you can add each element to the DataSet.
Share part of your code, so that it will be easier to help.
How do i get the body of a HTTP get request with the javax.ws.rs library?
I tried:
Response response = service.path(path).request().get();
String body = response.readEntity(String.class);
but that doesn't work. Instead i get this exception: java.lang.NoClassDefFoundError: javax/ws/rs/core/NoContentException
Then i tried:
Response response = service.path(path).request(MediaType.APPLICATION_JSON_TYPE).get();
String body = response.readEntity(JSONObject.class);
because I should actually get a JSON String back but i don't need it as JSON Object, that's the reason why i tried it like above before.
But that doesn't work at all, i even can't compile and get the (IntelliJ) message
no instance(s) of type variable(s) exist so that JSONObject conforms to String inference variable T has incompatible bounds: equality constraints: JSONObject upper bounds: Object, String
Addition:
I get 200 as response status so everything worked fine and when i do the same in e.g. Postman or Fiddler it works.
You can do this by using Jackson: first you create object from body
ObjectMapper mapper = new ObjectMapper();
InputStream responseBody = response.getBody().in();
JSONObject jsonobject = mapper.readValue(responseBody, JSONObject.class);
Then transform jsonobject to string:
String jsonInString = mapper.writeValueAsString(jsonobject);
In this specific case it should also work with
Response response = service.path(path).request(MediaType.APPLICATION_JSON_TYPE).get();
String body = response.readEntity(String.class);
because it tries to read the Entity and construct an object of the given type out of it. So I think that should work.
I want to parse my json string at run time. But, the problem is my json string is not a valid one due to some issues. Is there any way to parse the json with validation. My json string looks like this:
{"page_1":"{\"city\":\"Delhi\",\"locality\":\"Alaknanda\",\"Name_of_Person\":\"Varun Patil\",\"User_email_address\":\"varun.vap#gmail.com\",\"user_phone_number\":\"\",\"sub_locality\":\"\",\"street_name\":\"Pune\",\"home_plot_no\":\"xyz\",\"pin_code\":\"411060\",\"project_society_build_name\":\"\",\"landmark_reference_1\":\"\",\"landmark_reference_2\":\"\",\"No_of_Schools\":20,\"No_of_Hospitals\":20,\"No_of_Metro\":0,\"No_of_Mall\":20,\"No_of_Park\":20,\"Distance_of_schools\":1.51,\"Distance_of_Hospitals\":2.5,\"Distance_of_Metro\":0,\"Distance_of_Mall\":1.9,\"Distance_of_Park\":1.1,\"lat\":28.5304408,\"lng\":77.2505733,\"ipinfo\":{\"ip\":\"59.88.97.45\",\"hostname\":\"No Hostname\",\"city\":\"Pune\",\"region\":\"Maharashtra\",\"country\":\"IN\",\"loc\":\"18.5333,73.8667\",\"org\":\"AS9829 National Internet Backbone\",\"postal\":\"411001\"}}","page_2":"{\"home_type\":\"Flat\",\"area\":\"1000\",\"beds\":\"2 BHK\",\"bath_rooms\":2,\"building_age\":\"3\",\"floors\":\"\",\"balcony\":1,\"amenities\":\"regular\",\"amenities_options\":{\"gated_security\":\"\",\"physical_security\":\"\",\"cctv_camera\":\"\",\"controll_access\":\"\",\"elevator\":\"\",\"power_back_up\":\"\",\"parking\":\"\",\"partial_parking\":\"\",\"onsite_maintenance_store\":\"\",\"open_garden\":\"\",\"party_lawn\":\"\",\"amenities_balcony\":\"\",\"club_house\":\"\",\"fitness_center\":\"\",\"swimming_pool\":\"\",\"party_hall\":\"\",\"tennis_court\":\"\",\"basket_ball_court\":\"\",\"squash_coutry\":\"\",\"amphi_theatre\":\"\",\"business_center\":\"\",\"jogging_track\":\"\",\"convinience_store\":\"\",\"guest_rooms\":\"\"},\"interior\":\"regular\",\"interior_options\":{\"tiles\":\"\",\"marble\":\"\",\"wooden\":\"\",\"modular_kitchen\":\"\",\"partial_modular_kitchen\":\"\",\"gas_pipe\":\"\",\"intercom_system\":\"\",\"air_conditioning\":\"\",\"partial_air_conditioning\":\"\",\"wardrobe\":\"\",\"sanitation_fixtures\":\"\",\"false_ceiling\":\"\",\"partial_false_ceiling\":\"\",\"recessed_lighting\":\"\"},\"location\":\"regular\",\"location_options\":{\"good_view\":\"\",\"transporation_hub\":\"\",\"shopping_center\":\"\",\"hospital\":\"\",\"school\":\"\",\"ample_parking\":\"\",\"park\":\"\",\"temple\":\"\",\"bank\":\"\",\"less_congestion\":\"\",\"less_pollution\":\"\"},\"maintenance\":\"\",\"maintenance_value\":\"\",\"near_by\":{\"school\":\"\",\"hospital\":\"\",\"mall\":\"\",\"park\":\"\",\"metro\":\"\"},\"city\":\"Delhi\",\"locality\":\"Alaknanda\",\"token\":\"9a2a8bf359494054f98c80009b5bd0e7\"}"}
I tried the following methods:
String result = java.net.URLDecoder.decode(jsonstring, "UTF-8");
String withCharacters = StringEscapeUtils.unescapeHtml(jsonstring);
JSONObject json = (JSONObject)new JSONParser().parse(jsonstring);
System.out.println("city=" + json.get("city"));
System.out.println("locality=" + json.get("locality"));
Nothing works for me and any help will be appreciated.
You have some escaped json inside your main json structure. That means it's valid json, but after parsing the main structure you have to parse the value of page_1 (and probably all remaining pages as well). Try this:
JSONParser parser = new JSONParser();
JSONObject json = (JSONObject)parser.parse(jsonstring);
JSONObject nestedJson = (JSONObject)parser.parse(json.get("page_1"));
System.out.println("city=" + nestedJson.get("city"));
I'm having a problem regarding a json string, i acquire with the Apache http client, containing german umlauts.
The mapping of json strings is only working, if the string does not contain any german umlaut, otherwise i get an "JsonMappingException: Can not deserialize instance of [...] out of START_ARRAY.
The Apache http client is set with "Accept-Charset" to HTTP.UTF-8, but as result i always get e.g. "\u00fc" instead "ü". When i manually replace e.g. "\u00fc" with "ü" the mapping works perfect.
How can i get a utf-8 encoded json response from Apache http client?
Or is the server output the problem?
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
httpclient = new DefaultHttpClient(params);
httpclient = new DefaultHttpClient(params);
HttpGet httpGetContentLoad = new HttpGet(url);
httpGetContentLoad.setHeader("Accept-Charset", "utf-8");
httpGetContentLoad.setParams(params);
response = httpclient.execute(httpGetContentLoad);
entity = response.getEntity();
String loadedContent = null;
if (entity != null)
{
loadedContent = EntityUtils.toString(entity, HTTP.UTF_8);
entity.consumeContent();
}
if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode())
{
throw new Exception("Loading content failed");
}
closeConnection();
return loadedContent;
And the json code is mapped here:
String jsonMetaData = loadGetRequestContent(getLatestEditionUrl(newspaperEdition));
Newspaper loadedNewspaper = mapper.readValue(jsonMetaData, Newspaper.class);
loadedNewspaper.setEdition(newspaperEdition);
Update 1:
JsonMetaData is type of String containing the fetched json code.
Update2:
This code i use to transform the json output to me needs:
public static String convertJsonLatestEditionMeta(String jsonCode)
{
jsonCode = jsonCode.replaceFirst("\\[\"[A-Za-z0-9-[:blank:]]+\",\\{", "{\"edition\":\"an-a1\",");
jsonCode = jsonCode.replaceFirst("\"pages\":\\{", "\"pages\":\\[");
jsonCode = Helper.replaceLast(jsonCode, "}}}]", "}]}");
jsonCode = jsonCode.replaceAll("\"[\\d]*\"\\:\\{\"", "\\{\"");
return jsonCode;
}
Update3:
Json conversion example:
jsoncode before conversion:
["Newspaper title",
{
"date":"20130103",
"pages":
{
"1": {"ressort":"ressorttitle1","pdfpfad":"pathToPdf1","number":1,"size":281506},
"2":{"ressort":"ressorttitle2","pdfpfad":"pathToPdf2","number":2,"size":281533},
[...]
}
}
]
Jsoncode after conversion:
{
"edition":"Newspaper title",
"date":"20130103",
"pages":
[
{"ressort":"Resorttitle1","pdfpfad":"pathToPdf1","number":1,"size":281506},
{"ressort":"Resorttitle2","pdfpfad":"pathToPdf2","number":2,"size":281533},
[...]
]
}
Solution:
I started using GSON as #Boris suggested and the problem regarding umlauts is gone! Further more GSON really seems to be faster than Jackson Json.
A workaround would be to replace the characters manually following this table:
Sign Unicode representation
Ä, ä \u00c4, \u00e4
Ö, ö \u00d6, \u00f6
Ü, ü \u00dc, \u00fc
ß \u00df
€ \u20ac
Try parsing like that:
entity = response.getEntity();
Newspaper loadedNewspaper=mapper.readValue(entity.getContent(), Newspaper.class);
No reason to go through String, Jackson parses InputStreams directly. Also Jackson will automatically detect the encoding if you use my proposed approach.
EDIT By the way consider using GSON JSON parsing library. It is even faster than Jackson and easier to use. However, Jackson recently started parsing XMl, too, which is a virtue.
EDIT2 After all you have added as details I would suppose the problem is with the server implementation of the services - the umlauts are not to be unicode escaped in the json - UTF 8 is native encoding for it. Why don't you instead of manually replace e.g. "\u00fc" with "ü" do it via regex?