RestAssured JsonPath to String - java

Is there a way to convert the whole JSON path data to a string in Java?
I am working on APIs and their responses are in JSON format. It is easy to understand the JSON structure through Postman/WireShark but I am trying to run an API request through Java, grab the response, convert the raw response to JSON, convert JSON response to a string format and print it. The method '.getString()' is to access a particular element and not the whole data. The method '.toString()' does not work on JSON data either.
JsonPath json = (ConvertRawFiles.rawtoJSON(response));
String id = json.get("id");
log.info("The id is " + id);
JsonPath json = (ConvertRawFiles.rawtoJSON(response));
String complete_json_data = ???;
log.info("The complete json data is " + complete_json_data);
The code snippet which is mentioned "???" is what I was trying to achieve.

The methods which can convert a JsonPath object into a String are:
JsonPath json = (ConvertRawFiles.rawtoJSON(response));
String complete_json_data = json.prettify();
and
JsonPath json = (ConvertRawFiles.rawtoJSON(response));
String complete_json_data = json.prettyPrint();

var obj = { "field1":"foo", "age":55, "city":"Honolulu"};
var myJSON = JSON.stringify(obj);

Related

Why does the String coming in POST request body come with additional quotes and get not a JSON Object

I am calling a RestFul API written in Java that consumes plain text or JSON and returns a response in JSON. I am using gson library to generate and parse my fields. I am calling the api from an Android simulation where I user retrofit2 library and GsonConverterFactory.
The generated String seems fine. I am not using a POJO, just a generic HashMap which I then convert to a String.
Generated gson from Android is {"password":"K16073","userid":"K16073"}
Code given below.
At the API service, the string received is wrapped with additional double quotes.
Printed String including the quotes in the beginning and end "{\"password\":\"K16073\",\"userid\":\"K16073\"}"
Because of this I am getting java.lang.IllegalStateException: Not a JSON Object: "{\"password\":\"K16073\",\"userid\":\"K16073\"}"
I tried to remove the quotes and then I get com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Expected name at line 1 column 2 path $.
/* Android code */
Gson gson = new GsonBuilder()
.setLenient()
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(myRFReceivingApis.BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
Map<String, String> userData = new HashMap<>();
userData.put("userid",edtTxtUserId.getText().toString());
userData.put("password",editTxtPassword.getText().toString());
Gson gson = new Gson();
System.out.println(" generated gson " +gson.toJson(userData));
call = ApiClient.getInstance().getMyApi().callLogin(gson.toJson(userData));
call.enqueue(new Callback<Object>() {
#Override
public void onResponse(Call<Object> call, Response<Object> response) {
textViewResp.setText(response.body().toString());
:
/* End of Android code */
API Service code in Java
#POST
#Produces(MediaType.APPLICATION_JSON)
#Consumes({MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON})
#Path("login")
public String RFLoginNew(String jsonString) {
String result = jsonString.substring(1, jsonString.length() - 1);
System.out.println(" Json String "+result);
// tried using JsonParser -- line 1 below
JsonObject o = JsonParser.parseString(result).getAsJsonObject();
// tried using Gson gson.fromJson
Gson gson = new Gson();
JsonElement element = gson.fromJson (result, JsonElement.class); //Converts the json string to JsonElement without POJO
JsonObject jsonObj = element.getAsJsonObject(); //Converting JsonElement to JsonObject
// --line 2 below
System.out.println(" RFLoginNew struser "+ jsonObj.get("userid").getAsString());
I am not getting the correct json format. I am not sure what is wrong with the way jsonString is generated.
Cause
You are making double serialization.
call = ApiClient.getInstance().getMyApi().callLogin(gson.toJson(userData));
Here your map gets serialized to json string, and then this json gets serialized a second time when request is sent.
Fix
Serialize only once on frontend - whatever library you are using(i don't do android stuff) should have method where you supply the payload as an Оbject - the method argument should be the map, userData in your case.
call = ApiClient.getInstance().getMyApi().callLogin(userData);
Something like that.
Or double deserialization on backend - deserialize to String, then deserialize the resulting string again to whatever you need.
String jsonString = gson.fromJson(doubleJson, String.class);
Map<String, String> result = gson.fromJson(jsonString, Map.class);
System.out.println(result);

In Java how to easily get the value of a nested key from a JSON String / Object

I am using Java.
I have a string that I have converted to a JSON Object.
I want to extract the value of one of the Keys.
At the moment I am using this code:
String imageId = myJsonObject.getJSONObject("meta")
.getJSONObject("verification")
.getJSONObject("derivedData")
.getJSONArray("images")
.getJSONObject(0)
.getString("imageID");
This code works but surely there must be an easier way. In javascript I could access the value simply by writing this:
myJsonObject.meta.verification.derivedData.images[0].imageId
You may need to install library such as JsonPath to help you select values from a JSON object
An example to help understand better.
You can use external library Gson
Gson gson=new Gson();
/*You can convert to your DTO as well */
Map<Object,Object> map = gson.from(myJsonObject,Map.class);
Other way is using objectmapper example of fasterxml.
ObjectMapper objectMapper=new ObjectMapper();
/*You can convert to your DTO as well */
objectMapper.readValue(data, Map.class);
Try JsonNode by below step
String imageId= jsonNode.
findPath("meta")
.findPath("verification")
.findPath("derivedData")
.findPath("images")
.get (0).findPath ("imageID").asText ();
You need to use the 'Java API for JSON Binding' JSON-B instead of JSON-P. Using JSON-B you can serialize and deserialize between Java objects and data streams and access values of objects POJO style (similar to what you expect).
API details can be found here
A quick start tutorial can be found here and at many website only google search away..
I have created a small class for this purpose which can basically get value from json using a path only used google.gson
https://github.com/izeryab/JsonParser
Here is how to use this for getting nested value from json:
public class Main {
public static void main(String[] args) {
String json = "{\"data\":[{\"stuff\":[\n" + " { \"onetype\":[\n"
+ " {\"id\":1,\"name\":\"John Doe\"},\n" + " {\"id\":2,\"name\":\"Don Joeh\"}\n"
+ " ]},\n" + " {\"othertype\":[\n" + " {\"id\":2,\"company\":\"ACME\"}\n" + " ]}]\n"
+ "},{\"otherstuff\":[\n" + " {\"thing\":\n" + " [[1,42],[2,2]]\n" + " }]\n" + "}]}";
String name = JsonUtil.getJsonElementFromJsonStringUsingPath("data>0>stuff>0>onetype>0>name", json, ">").getAsString();
int id= JsonUtil.getJsonElementFromJsonStringUsingPath("data>0>stuff>0>onetype>0>id",json,">").getAsInt();
System.out.println("id : "+id);
System.out.println("name : "+name);
}
}
Corresponding JAVA DOCS:
https://izeryab.github.io/JsonParser/JsonUtil.html
You can use GSon, I've used it before (see below)
// Convert to a JSON object to print data
JsonParser jp = new JsonParser(); //from gson
JsonElement root = jp.parse(new InputStreamReader((InputStream) request.getContent())); //Convert the input stream to a json element
JsonObject rootobj = root.getAsJsonObject(); //May be an array, may be an object.
JsonArray jsonDataArray = rootobj.getAsJsonArray("data");
JsonPrimitive totalJson = rootobj.getAsJsonPrimitive("total");
JsonPrimitive nextJson = rootobj.getAsJsonPrimitive("next");

Java Parse String

I have a String in a following format:
{"id":"1263e246711d665a1fc48f09","facebook_username":"","google_username":"814234576543213456788"}
but sometimes this string looks like:
{"id":"1263e246711d665a1fc48f09","facebook_username":"109774662140688764736","google_username":""}
How can I extract those values if I do not know the index of substrings as they will change for different cases?
That looks like json format, you should give a look to the Gson library by google that will parse that string automatically.
Your class should look like this
public class Data
{
private String id;
private String facebook_username;
private String google_username;
// getters / setters...
}
And then you can simply create a function that create the object from the json string:
Data getDataFromJson(String json){
return (Data) new Gson().fromJson(json, Data.class);
}
That String is formated in JSON (JavaScript Object Notation). Is a common language used to transfer data.
You can parse it using Google's library Gson, just add it to your class path .
Gson gson = new Gson();
//convert the json string back to object
DataObject obj = gson.fromJson(br, DataObject.class); //The object you want to convert to.
https://github.com/google/gson
Check this out on how to convert to Java Object
Parsing as JSON notwithstanding, here's a pure string-based solution:
String id = str.replaceAll(".*\"id\":\"(.*?)\".*", "$1");
And similar for the other two, swapping id for the other field names.

Rest Assured - deserialize Response JSON as List<POJO>

I have a POJO Artwork. I'm retrieving a List of those objects from a RESTful webservice in the HTTP response body in JSON format. I'm trying to write a Rest Assured-based test that would analyze the returned list. The code looks like this:
Response response = get("/artwork");
List returnedArtworks = response.getBody().as(List.class)
The problem is, I can't get Rest Assured to parse the returned JSON as List<Artwork>. Instead, I get a List<LinkedHashMap>. The map has a proper structure, i.e. could be mapped by Jackson to Artwork object, but I'd like to avoid mapping it manually.
JSON mappings in my model are OK, because when I map single object like this:
Artwork returnedArtwork = response.getBody().as(Artwork.class);
it works fine.
Is it possible to get returnedArtworks as List<Artwork>?
You can do this:
List<Artwork> returnedArtworks = Arrays.asList(response.getBody().as(Artwork[].class));
The trick is to deserialize JSON to an array of objects (because there is no difference between the JSON string of an array or a list), then convert the array to a list.
this solution works for version 3.0.2 (io.restassured):
JsonPath jsonPath = RestAssured.given()
.when()
.get("/order")
.then()
.assertThat()
.statusCode(Response.Status.OK.getStatusCode())
.assertThat()
.extract().body().jsonPath();
List<Order> orders = jsonPath.getList("", Order.class);
This will extract the objects for a structure like this:
public class Order {
private String id;
public String getId(){
return id; }
public void setId(String id){
this.id = id;
}
}
with the given json:
[
{ "id" : "5" },
{ "id" : "6" }
]
By using Google's Gson library you can easily parse it to List<Artwork>. Try below code
Gson gson = new Gson();
List<Artwork> returnedArtworks = gson.fromJson(jsonStr, new TypeToken<List<Artwork>>(){}.getType());
//* where jsonStr is the response string(Json) receiving from your Restful webservice
Rest-assured provide an as(java.lang.reflect.Type) next to the version expecting a Class used in the question.
java.lang.reflect.Type type; //TODO defines the type.
Response response = get("/artwork");
List<Artwork> returnedArtworks = response.getBody().as(type)
In my opinion the way the type variable depends from the serialization lib that is used.
If using Gson, as pointed out by Purushotham's answer, TypeToken can be used. I prefer using it directly in rest-assured:
Type type = new TypeToken<List<Artwork>>(){}.getType();
Response response = get("/artwork");
List<Artwork> returnedArtworks = response.getBody().as(type)
When using Jackson, the solution is to use the TypeFactory (javadoc, source) to tell to which type it should be de-serialized:
Type type = TypeFactory.defaultInstance().constructCollectionLikeType(ArrayList.class, Artwork.class);
Response response = get("/artwork");
List<Artwork> returnedArtworks = response.getBody().as(type)
With REST assured 3.0.2 you can simply check if content exists in the array
when().get("/artwork").then().body("artworks", hasItem("some art");
//or check multiple values in array
when().get("/artwork").then().body("artworks", hasItems("some art", "other art");
This way you will avoid complexity in your code by converting JSON to list more examples how to check response content can be found link

Split JSON string into two variables

I have a JSON/string/array, not sure what it is now as it’s been through a spinner and is now in a String variable, it was JSON. It looks like this: {“BusName”:”Joe”,”BusPhone”:”1234567890”} what I want to do is split it into two variables, (buiessname = BusName and businessphone = BusPhone), and also remove all the {}, ” and :’s.
I could use split and replace but it would be a messy function, is there some kind of Java/JSON function that can handle it for me??? How would you guys go about it???
Cheers,
Mike.
You can use JSONObject to parse the JSON String into a real object.
String jsonStr = "{\“BusName\”:\”Joe\”,\”BusPhone\”:\”1234567890\”}";
JSONObject myJsonObj = new JSONObject(jsonStr);
String busName = myJsonObj.getString("BusName");
String busPhone = myJSONObj.getString("BusPhone");
I'd suggest using json-simple to parse the JSON data, rather than trying to directly manipulate the string yourself. For example, you might do:
JSONObject data = (JSONObject)JSONValue.parse(text);
String businessName = (String)data.get("BusName");
String businessPhone = (String)data.get("BusPhone");
You can find more examples here: http://code.google.com/p/json-simple/wiki/DecodingExamples.

Categories

Resources