Getting String value using JsonPath Java - java

Im using JsonPath to Assert on some of the values returned from an api response but having a small issue with asserting the response.
Heres the response i get:
[{"Id":75969,StartDate":"2016-07-01","EndDate":"2021-04-30","duration":5640}]
Lets say i want to Assert on the Start date.
The method I created looks like this:
public void checkStartDate(String expectedStartDate) {
String responseBody = response.getBody().asString();
JsonPath values = new JsonPath(responseBody);
Assert.assertEquals(expectedStartDate,values.getString("startDate"));
}
The expectedStartDate that i pass in to the method is 2016-07-01 and the date i get back from the JsonPath object is [2016-07-01] which causes the assertion to fail.
Does anyone know what i can do to with JsonPath in order to remove the square braces from the value that im extracting from the response string?

This might help you. Try the below code :
public void checkStartDate(String expectedStartDate) {
String responseBody = response.getBody().asString();
String startDate = JsonPath.read(responseBody, "$.[0].StartDate");
Assert.assertEquals(expectedStartDate, startDate);
}

When you read with "getList", you will get the exact value.
JsonPath values = new JsonPath(responseBody);
List<String> valuesToRead = values.getList("StartDate");
for (String value : valuesToRead) {
System.out.println(value);
}

I think the problem is the reponse is an array of objects, rather than just a single object? So you want to check against jp.getString("[0].StartDate")
Working example:
JsonPath jp = JsonPath.from("[{\"Id\":75969,\"StartDate\":\"2016-07-01\",\"EndDate\":\"2021-04-30\",\"duration\":5640}]");
System.out.println("2016-07-01".equals(jp.getString("[0].StartDate")));
Prints: true

Related

How to remove any type of Key from JSON

This is part of my JSON:
{
"expressions": {
"storyId": "doesNotMatter"
},
"facts": { }
}
I wish to remove the key 'storyId' from my JSON. How can I do it by converting my JSON into a string and using Regex?
After removing the undesired text my JSON should like like this:
{
"expressions": {
},
"facts": { }
}
Note: I don't see my original JSON and can't know who or what the wrapper element is.
I wouldn't recommend using regex for such thing, the better choice would be using a library for parsing json, remove the value, and then turn it into a string again.
JSONObject jsonObject = new JSONObject(input);
jsonObject.getJSONObject("expressions").remove("storyId");
String output = jsonObject.toString();
if you really want to use regex, you can use the follow
jsonString.replaceAll("(\\\"storyId\\\"|\\'storyId\\')\\s*:\\s*(\\\"[^\\\"]*\\\"|'[^\\\"]*')\\s*,?", "");
but just make sure that storyId is really a string, otherwise this regex won't work.
edit: updated my answer, if you want a function that get the parameter to remove with regex,
void replaceAllKeys(String keyName, String jsonAsString) {
String pattern = String.format("(\\\"%s\\\"|\\'%s\\')\\s*:\\s*(\\\"[^\\\"]*\\\"|'[^\\\"]*')\\s*,?", keyName, keyName);
return jsonAsString.replaceAll(pattern, "");
}
First i am assuming you will get all json object in jsonObj and then call remove() by passing your json key like following:
jsonObj.getAsJsonObject("expressions").remove("storyId");

How to get the elasticsearch json response using aggregations in spring-data-elasticsearch?

I have the following:
I notice that at the end of running the code, if I print out aggregations.asMap().get('subjects');
I am getting:
org.elasticsearch.search.aggregations.bucket.terms.StringTerms#6cff59fa
Printing out "aggregations" gives me: org.elasticsearch.search.aggregations.InternalAggregations#65cf321d
What I really want is the entire string/json response that is normally returned if you were to curl on elasticsearch to get aggregations. How do I get to the raw response from the aggregation query? Also, is there a way to iterate and print out what's in those "wrapped up" objects?
https://github.com/spring-projects/spring-data-elasticsearch/blob/ab7e870d5f82f6c0de236048bd7001e8e7d2a680/src/test/java/org/springframework/data/elasticsearch/core/aggregation/ElasticsearchTemplateAggregationTests.java
#Test
public void shouldReturnAggregatedResponseForGivenSearchQuery() {
// given
SearchQuery searchQuery = new NativeSearchQueryBuilder()
.withQuery(matchAllQuery())
.withSearchType(COUNT)
.withIndices("articles").withTypes("article")
.addAggregation(terms("subjects").field("subject"))
.build();
// when
Aggregations aggregations = elasticsearchTemplate.query(searchQuery, new ResultsExtractor<Aggregations>() {
#Override
public Aggregations extract(SearchResponse response) {
return response.getAggregations();
}
});
// then
System.out.println(aggregations); // gives me some cryptic InternalAggregations object, how do I get to the raw JSON normally returned by elasticsearch?
System.out.println(aggregations.asMap().get("subjects")); // gives me some StringTerms object I have no idea how to iterate over to get results
}
You cannot get the raw JSON response this way, since Spring Data Elasticsearch will take care of parsing it for you, that's the whole point.
If you need to parse those buckets, you can do it like this easily:
...
StringTerms subjects = aggregations.asMap().get("subjects");
for (Terms.Bucket bucket : subjects.getBuckets()) {
String key = bucket.getKey();
long docCount = bucket.getDocCount();
// do something with the key and the doc count
}
If you really want to see the JSON being returned, what you can do is to re-write the parsed Aggregations object into JSON using serialization, but that won't really be helpful:
InternalAggregations aggregations = ...;
XContentBuilder jsonBuilder = JsonXContent.contentBuilder();
aggregations.toXContent(jsonBuilder, ToXContent.EMPTY_PARAMS);
String rawJson = jsonBuilder.string();
Set Size of EsRequest to Zero
Get Esresponse.toString()
Convert String to Json
Get aggregation field from Json.

How can i automatically replace two separate ID's in Json object file using java, RestAssured testing web services

I am testing web services using java, RestAssured, groovy notation etc.
I have got separate modules that are depending on each other in terms of passing request methods. such as POST, PUT. when i want to do a POST request on a module, in json schema i have to pass existing id from two different modules into the file. i.e site_id and group_id respectively.
Below is my json schema that i have store in the file:
{
"site_id": 10,
"permission": "admin.client.add",
"group_id": 3
}
Below is my code: from my page class as am using Page object framework.
public String postpermission(String siteid, String grpid)
throws FileNotFoundException, IOException, ParseException {
Object obj = parser.parse(new FileReader(path
+ "/resources/permission/postpermission.json"));
String d = obj.toString();
Object objecc = parser.parse(d.replaceFirst("3", grpid));
Object objec = parser.parse(d.replaceFirst("10", siteid));
JSONObject jsonPostBody = (JSONObject) objec;
jsonPostBody = (JSONObject) objecc;
return postRequest(jsonPostBody, permissionURI, 201, "data.id",
"postpermission()", false);
}
Below is code from my test class:
#Test
public void postpermission() throws FileNotFoundException, IOException,
ParseException {
String siteid = sites.postsites();
String grpid = group.postGroup();
String permid = permission.postpermission(siteid, grpid);
permission.deletepermission(permid);
}
Note: with this code i can replace one id but it doesn't replace the second one. Please can anyone provide me with better way to make it work.
Thanks in anticipation.
You need to notice that the replaceFirst method will not change the original String, it will return the result as a new String.
So in your case, you need to reassign the first replaceFirst result back to variable d. The code as below:
d = d.replaceFirst("3", grpid);
Object objec = parser.parse(d.replaceFirst("10", siteid));
Or you can use simpler one:
Object objec = parser.parse(d.replaceFirst("3", grpid).replaceFirst("10", siteid));
One more suggestion about the JSON schema (I would like to call it json template) you have, it's better to have placeholders instead of using numbers.e.g.
{
"site_id": {site_id},
"permission": "admin.client.add",
"group_id": {group_id}
}
Also you may checkout this JSON template project if you need do more things on json template.

Getting a value from deep inside JSON

I am connecting to a third party API and getting back a long JSON string. I only need one value from it, but it is located pretty deep inside the hierarchy. Is there a simple way to get it, without going through the whole thing? I looked all over but nothing seems easy.
Here's my example:
"response":{"status":1,"httpStatus":200,"data":{"myDesiredInfo":"someInfo"},"errors":[],"errorMessage":null}}
I've been trying to use Gson so I can get this blob as a JsonObject. I was sure there's something simple, like this:
jsonObject.get("myDesiredInfo")
or at the minimum something like this:
jsonObject.get("response.data.myDesiredInfo")
But it doesn't seem to exist.
So is there any parser out there that will allow me to do this?
This is my json string
String s="{"age":0,"name":"name","email":"emailk","address":{"housename":"villa"}}";
I use following code to get housename
JsonElement je = new JsonParser().parse(s);
JsonObject asJsonObject = je.getAsJsonObject();
JsonElement get = asJsonObject.get("address");
System.out.println(s + "\n" + get);
JsonObject asJsonObject1 = get.getAsJsonObject();
JsonElement get1 = asJsonObject1.get("housename");
System.out.println(get1);
The Following is my output :
{"age":0,"name":"name","email":"emailk","address":{"housename":"villa"}}
{"housename":"villa"}
"villa"
I don't think there is another way to do this. I also tried to do in other ways but i didn't get any output.
The following way you can retrieve from your jsonObject.
JSONObject jObject = new JSONObject(yourresponse);
Log.i("Desired Info is ",jObject.getJSONObject("response").getJSONObject("data").getString("myDesiredInfo"));
I wrote a little utility method that uses Gson's API to get a value as String from a JSON object, based on a java.util.List of values. So for my original question the list objects will be "response", "data", "myDesiredInfo."
Surely this can be improved on, but it's a start.
/*
* Takes a JsonObject and parses it for a primitive value, going level by level
* according to the values in #infos
*/
public static String parseJson(JsonObject json, List<String> infos) {
try {
if(infos.size() == 0) {
return json.toString();
}
JsonElement je = json.get((String)infos.get(0));
infos.remove(0);
if(je instanceof JsonObject) {
return parseJson(je.getAsJsonObject(), infos);
} else {
return je.getAsString();
}
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
Most languages have a JSON decoding library, a lot of them native. No idea what language you're using so here's PHP as an example:
$jsonObj = json_decode($json);
$json->response->data->myDesiredInfo;
Ruby, Python, Java - all these languages have good libraries.

How to return PHP array and receive it with Java

I have this on my webservice:
function listar($username)
{
$result = mysql_query("SELECT Name FROM APKs WHERE Tipo=0");
//$registo = mysql_fetch_array($result);
$numero = 0;
while($registo = mysql_fetch_array($result))
{
$regs[$numero] = $registo['Name'];
$numero++;
}
return $regs;
//return mysql_fetch_array($result);
}
in Java, after the SOAP call (not relevant now) I read it this way:
Object response = envelope.getResponse();
String x = response.toString();
I need to access which one of those fields (selected from the database) so I thought, why not split the array into strings?
I tried two methods:
String[] arr=x.split(" ");
System.out.println("Array :"+arr.length);
for(int i=0;i<arr.length;i++)
{
..
}
StringTokenizer stArr=new StringTokenizer(x," ");
while(stArr.hasMoreTokens())
{
...
}
But none of them worked, whick make me believe I'm returning badly the array in first place.
Any help?
UPDATE:
So I'm using again xsd:string;
Now I have on my webservice return json_encode($regs);
To convert the object from the response I'm using a specific google api
http://www.mkyong.com/java/how-do-convert-java-object-to-from-json-format-gson-api/
Object response = envelope.getResponse();
Gson gson = new Gson();
String jstring = gson.toJson(response);
But I'm with difficulty parsing the "jstring" because it's format: "[\"SOMETHING\",\"SOMETHING\",\"SOMETHING\",\"SOMETHING\",.....]". I have not any identifier to get those values.
How can I extract those dynamic values and assign them to String[]?
USE:
json_encode($array); in PHP
and
JSONObject in Java to read.
See this example: http://www.androidcompetencycenter.com/2009/10/json-parsing-in-android/
UPDATE
Change the line:
$regs[$numero] = $registo['Name'];
to:
$regs[] = array('name' => $registo["name"]);
If you need to get the ID, you also can do:
$regs[] = array('name' => $registo["name"], 'id' => $registo["id"]);
FORGET:
The mysql_fetch_array returns a real array not a string. It's not needed to split a string.
Be sure that your PHP Web Service is returning a xsd:array
Generate a new proxy using some generator like http://www.soapui.org. Just use the proxy. Nothing else.
Try to use JSON and you can esy build easy object and read it.

Categories

Resources