Rest-assured. get value from another value - java

I have a json response something like this:
"results": [
{
"id": "1",
"name": "YYY",
"shortName": "Y"
},
{
"id": "2",
"name": "XXX",
"shortName": "X"
},
{
"id": "3",
"name": "ZZZ",
"shortName": "Z"
}
]
I want to get id value when I send name value. For example if name = ZZZ return me id value in this case 3 using rest assured

Json path json-path-2.9.0 with rest-assured
import static com.jayway.restassured.path.json.JsonPath.from;
below JsonPath query
from(response).getList("results.findAll { it.name=='ZZZ' }.id").toString() //returns 3
from(response).getList("results.findAll { it.name=='XXX' }.id").toString() //returns 2

Related

find the record of OutterObject where InnerObject id is x and date is most recent

I am trying to get the id of the OutterObject where the InnerObject id is a specific value and the date is the most recent of all InnerObject of all OutterObject.
I'm trying to achieve that with streams.
Searching for id "ab", it should return "def"
here is a json example of the structre.
{
"OutterObject": [
{
"id": "abc",
"InnerObject": [
{
"id": "ab",
"date": "1"
},
{
"id": "de",
"date": "2"
},
{
"id": "ab",
"date": "3"
}
]
},
{
"id": "def",
"InnerObject": [
{
"id": "ab",
"date": "9"
},
{
"id": "de",
"date": "3"
},
{
"id": "ab",
"date": "1"
}
]
}
]
}
Use flatMap to gather all objects in the same array :
OutterObject.stream().flatMap(outer -> outer.getInnerObject().stream());
Use max() and Comparator to get the higher value
Combine both to get something like :
Optional<Date> maxDate = OutterObject.stream().flatMap(outer -> outer.getInnerObject().stream()).max(Comparator.comparing(InnerObject::getDate));
This is solved with :
Optional<SimpleImmutableEntry<String, InnerObject>> mostRecentOutterObjectId= MasterObject.getOutter().stream()
.flatMap(outter-> outter.getInner().stream()
.map(inner-> new SimpleImmutableEntry<String, InnerObject>(outter.getId(), inner)))
.filter(outterMap-> StringUtils.equals(outterMap.getValue().getId(), "ab")))
.max((innerA,innerB) -> innerA.getValue().getDate().compareTo(innerB.getValue().getDate()));
I am open to improvement if you see some.

I need to send the request correctly, but I don't know how to get the required values from objects

How to get a new list from the list of objects?
I need a new list of objects to POST request
this list of objects i get from response:
{
"success": true,
"body": {
"users": [
{
"type": "unknown",
"data": [
{
"id": "8",
"firstName": "Jackson",
"lastName": "Baker",
"group": "false"
},
{
"id": "11",
"firstName": "Charlotte",
"lastName": "Garcia",
"group": "false"
},
{
"id": "7",
"firstName": "Henry",
"lastName": "Thompson",
"group": "false"
},
{
"id": "24",
"firstName": "Elijah",
"lastName": "Miller",
"group": "false"
}
]
}
]
}
}
I need to form a new object from response:
{
"success": true,
"body": {
"users": [
{
"type": "unknown",
"data": [
{
"id": "8",
"group": "false"
},
{
"id": "11",
"group": "false"
},
{
"id": "7",
"group": "false"
},
{
"id": "24",
"group": "false"
}
]
}
]
}
}
This new list of object I need to post a request.
I have a JSON Schema, but i don't know how i can make this structure.
My problem is that I can't get the values from fields. I'm using the path "body.users.data.find {it.id} .id" but it finds the id array but I need a users list with values from two fields.
As the users node and data node are all list type, you need use two loop:
import groovy.json.JsonSlurper
// text is your json response text
def result = new JsonSlurper().parseText(text)
result.body.users.each{it.data.each{it.remove("firstName");it.remove("lastName")}}
// result is the what you wanted
println(result)

How to do Parsing JSON string in Java with nested arrays

Starting from the similar question,
Nested JSON Array in Java
I have a somewhat odd json as a response from a REST api(POST) call. I need to find out the id and name of the sub_items array in each items array element.
I tried like given below for which I am getting error like
org.json.JSONException: JSONObject["items.sub_items"] not found.
I also tried just 'sub_items' as the parameter also, but no. I am using GSON. No choice use others.
final JSONObject jsonObj = new JSONObject(JSON_STRING);
final JSONArray subItems = jsonObj.getJSONArray("items.sub_items");
final int n = subItems.length();
for (int i = 0; i < n; ++i) {
final JSONObject subI= subItems.getJSONObject(i);
System.out.println("id="+subI.getString("id"));
System.out.println("name="+subI.getString("name"));
}
The following is my json as a response from a REST api call.
{
"menu": {
"items": [{
"id": 1,
"code": "hot1_sub1_mnu",
"name": "Mutton",
"status": "1",
"sub_items": [{
"id": "01",
"name": "Mutton Pepper Fry",
"price": "100"
}, {
"id": "02",
"name": "Mutton Curry",
"price": "100"
}]
},
{
"id": "2",
"code": "hot1_sub2_mnu",
"name": "Sea Food",
"status": "1",
"sub_items": [{
"id": "01",
"name": "Fish Fry",
"price": "150"
}]
},
{
"id": "3",
"code": "hot1_sub3_mnu",
"name": "Noodles",
"status": "1",
"sub_items": [{
"id": "01",
"name": "Chicken Noodles",
"price": "70"
}, {
"id": "02",
"name": "Egg Noodles",
"price": "60"
}]
}
]
}}
As I said, my JSON is a response from an REST api call, and it is 7300 lines long, like shown below with the outline, as shown in code beautifier.
object {3}
infoTransferReqResp {1}
paramExtens : null
pageGroups {1}
pageGroups [1]
0 {4}
page_group_name : LFG - LG - Insured Summary
page_group_id : 8100
**pages [3]**
repeatingBlocks {1}
I needed to extract a string value 'questionText' from inside 'Pages' array. I used jsonPath() method with navigation path as given below which solved the problem.
JsonPath jsonPathEvaluator = response.jsonPath();
List<List<List<String>>> questions = jsonPathEvaluator.getList("pageGroups.pageGroups.pages.questions.questionText");
It gave me 3 ArrayLists one embedded in another corresponding to 3 arrays of 'pages'

Filter nested json data using jsonpath as in example

I am using jsonpath to filter.
Json(Dummy json just to explain) source String, which is basically a list of Operating systems and details of its programs etc. In this example, the OS whose id = 1403 is a windows 10 OS and has 2 features acchritecture and browser. There are more details to the browser feature as shown in json
[
{
"id": 1403,
"os": "window 10",
"features": [
{
"id": 1356,
"name": "architecture",
"value": [
{
"id": 1308,
"feature": [
{
"id": 1262,
"key": "name",
"value": "amd64"
}
]
}
],
"category": "cat1"
},
{
"id": 1357,
"name": "browser",
"value": [
{
"id": 1309,
"feature": [
{
"id": 1263,
"key": "name",
"value": "Firefox"
},
{
"id": 1265,
"key": "version",
"value": "187"
}
]
}
],
"category": "cat2"
}
]
},
{
"id": 2804,
"os": "window 7",
"features": [
{
"id": 2764,
"name": "architecture",
"value": [
{
"id": 2719,
"feature": [
{
"id": 2679,
"key": "name",
"value": "amd64"
}
]
}
],
"category": "cat1"
},
{
"id": 2765,
"name": "browser",
"value": [
{
"id": 2722,
"feature": [
{
"id": 2685,
"key": "name",
"value": "Chrome"
},
{
"id": 2684,
"key": "version",
"value": "87.0.4280.88"
}
]
}
],
"category": "cat2"
}
]
}
]
I want to be able to filter the json such that
features[*].name == 'browser' and features[*].value[*].feature[*].value == 'chrome'
What will be the JsonPath string that can help me achieve above query? The above query uses similar syntax used by JsonPath string but doesn't do the job. Its just to explain.
There is another example here gets Movie Title Given 'Starring' field
And would like to get the full OS json that fulfils this condition. In this case a array of OS which contains only one OS i.e. with id= 2804
[
{
"id": "2804",
...
}
]
I am stuck much before what aim to achieve. Here is my code to get all the OS that have "name=browser". I get the array but it only contains value[] items. I want it get the full json. It returns object with IDs- 1357, 2765.
List<Map<String, Object>> expensive = JsonPath.parse(jsonDataSourceString)
.read("$[*].features[*].[?(#.name == 'browser')]");
To get the outer array you need to use the filter like $[?(...)]
For your current use case, we need to use nested array filters. There is an open issue in JsonPath for filter on children level. (Refer here).
Luckily, there is a workaround suggested to use contains over here.
we can use the below expression to filter:
List<Object> expensive = JsonPath.parse(jsonDataSourceString)
.read("$[?(#.features[?(#.name == 'browser')].value[*].feature[*].value contains 'Chrome')]");
Prints the below output
{id=2804, os=window 7, features=[{"id":2764,"name":"architecture","value":[{"id":2719,"feature":[{"id":2679,"key":"name","value":"amd64"}]}],"category":"cat1"},{"id":2765,"name":"browser","value":[{"id":2722,"feature":[{"id":2685,"key":"name","value":"Chrome"},{"id":2684,"key":"version","value":"87.0.4280.88"}]}],"category":"cat2"}]}

how to create linked hash map object for this json

I am trying to call an API using Retrofit in android. For this API I need the input parameter JSON object in proper sequence.
Only if I have the json in required sequence I get successful response from the API, otherwise it gives an error. To handle this issue I got one solution that is to first create a LinkedHashMap of input parameter then create the JSON of that LinkedHashMap. This way I'm acheaving the response from api.
but right now im confused how to create linkedHash map for below json
{
"RequestXml": {
"Authenticate": {
"InterfaceCode": "1",
"InterfaceAuthKey": "AirticketOnlineWebSite",
"AgentCode": "MOS0000001",
"Password": "KGBW5P"
},
"BookTicketRequest": {
"TrackNo": "0$182967|4|1AO",
"MobileNo": "9099776464",
"AltMobileNo": "9898989898",
"Email": "abc#gmail.com",
"Address": "Test",
"ClientRequestID": "",
"Passengers": {
"Passenger": [
{
"PaxSeqNo": "1",
"Title": "Mr",
"FirstName": "Savan",
"LastName": "Test",
"PassengerType": "A",
"DateOfBirth": "01/12/1992",
"PassportNo": "RTTTTGGBGB56356",
"PassportExpDate": "01/12/2024",
"PassportIssuingCountry": "IND",
"NationalityCountry": "IND"
}
]
},
"Segments": {
"Segment": [
{
"TrackNo":"0$182967|4|1AO",
"SegmentSeqNo": "1",
"AirlineCode": "UK",
"FlightNo": "888",
"FromAirportCode": "BOM",
"ToAirportCode": "DEL",
"DepDate": "30/09/2019",
"DepTime": "14:00",
"ArrDate": "30/09/2019",
"ArrTime": "16:00",
"FlightClass": "E",
"MainClass": "Y"
}
]
},
"AdditionalServices": {
},
"TotalAmount": "4735",
"MerchantCode": "PAY9zJhspxq7m",
"MerchantKey": "eSpbcYMkPoZYFPcE8FnZ",
"SaltKey": "WHJIIcNjVXaZj03TnDme",
"IsTicketing": "Yes"
}
}
}

Categories

Resources