JSON Object changes randomly from api - java

I get data from an API in which the JSON object changes randomly, like if it is at "position": 1, now it will change randomly to "number": 1. So, how can I check in my application if the object is at "position": 1 or "number": 1 and use it as int?
JSON :-
{
"now": [{
"time": {
"starts_in": 0,
"ends_in": 79580,
"starts_at": 0,
"ends_at": "2018-01-21T08:00:00.788Z"
},
"coins": {
"free": 8,
"first_win": 16,
"max": 52,
"collected": 0
},
"unk1": -88317689,
"position": 1,
"xp_multiplier": 0,
"location_scid": {
"scid_type": 15,
"scid_id": 1
},
"tid": "TID_WANTED_3",
"location": "Terre",
"mode": {
"name": "Bty",
"color": "#0884FA",
"description": " The team wins!"
},
"unk4": 0,
"info": "",
"unk5": 0,
"unk6": 0
}, {
"time": {
"starts_in": 0,
"ends_in": 36380,
"starts_at": 0,
"ends_at": "2018-01-20T20:00:00.788Z"
},
"coins": {
"free": 24,
"first_win": 0,
"max": 32,
"collected": 0
}
}],
"later": [{
"time": {
"starts_in": 79580,
"ends_in": 165980,
"starts_at": "2018-01-21T08:00:00.788Z",
"ends_at": "2018-01-22T08:00:00.788Z"
},
"coins": {
"free": 8,
"first_win": 16,
"max": 52,
"collected": 0
},
"unk1": -88217689,
"position": 1,
"xp_multiplier": 0,
"location_scid": {
"scid_type": 15,
"scid_id": 7
},
"tid": "TID_GOLDRUSH_1",
"location": "Mine",
"mode": {
"name": "Grab",
"color": "#AA57CF",
"description": " An. "
}
}]
}
Thanks in advance :)

JSONObject c = //Your jsonObject;
String position = c.getInt("position");
String number = c.getInt("number");
if(position!=null){
//TODO You know it is position and it's int value
}else if(number!=null){
//TODO You know it is number and it's int value
}else{
//TODO Its neither of two
}

If you're using Gson to convert your JSON to a class, you can use both position and number as attributes for your destination class.
After that, check which one is null and which one is not and use that is not null as your number.

Just try this one,
JSONObject object = (Your jsonObject);
if(object.has("position")){
** do your code here **
}else if(object.has("number"){
** do your code here **
}

Related

JSON Object Navigation to nested value

I am new to JSON and trying to manipulate JSON for some validation
My JSON looks like this . I need to pick the JSON object based on the refcode and then get count of different object in that, and navigate deeper inside to get the key value pair. Can someone guide me how I can navigate.
{
"components": [
{
"id": 12,
"text": "ABC",
"refCode": "CO_ABC",
"patternCode": "0",
"components": [
{
"id": 1234,
"text": "types",
"refCode": "CO_TYPES",
"questions": [
{
"questionId": 122324,
"questionText": "Is this you",
"questionSequence": 1,
"questionRefCode": "QN_STAY",
"hasPreselectedAnswer": false,
"responsesMetadata": {
"cardinality": "single",
"patternCode": "5",
"dataType": "STRING",
"numberMin": null,
"numberMax": null
},
"choices": [
{
"choiceId": 5456,
"choiceRefCode": "YES",
"choiceText": "Yes",
"sequence": 1
},
{
"choiceId": 8798,
"choiceRefCode": "NO",
"choiceText": "No",
"sequence": 2
}
],
"editable": true,
"accessible": true
}
]
},
{
"id": 13,
"text": "State of stay",
"refCode": "CO_STATE",
"questions": [
{
"questionId": 1,
"questionText": "Which state do you stay",
"questionSequence": 2,
"questionRefCode": "QN_STATE",
"hasPreselectedAnswer": false,
"responsesMetadata": {
"cardinality": "multiple",
"patternCode": "1",
"dataType": "STRING",
"numberMin": null,
"numberMax": null
},
"choices": [
{
"choiceId": 1,
"choiceRefCode": "CH_AZ",
"choiceText": "Arizona",
"sequence": 1
},
{
"choiceId": 2,
"choiceRefCode": "CH_PA",
"choiceText": "Pennsylvania",
"sequence": 2
}
],
"accessible": true
}
]
}
]
}
]
}

How to get a child object in response with java streams

Alrighty I've been banging my head in a wall whole day and cant solve this issue. I am trying to find an id in a object list which is like 3 levels down the hierarchy with java stream. I know how to do it with for loop but I need to get it with stream.
json response is
"NumberOfOwners": 1,
"CurrentPage": 1,
"TotalItems": 1,
"TotalPages": 1,
"PageSize": 1,
"PageItems": [
{
"Id": 1560,
"Title": "PlsWrk",
"IsSubmitted": true,
"Owner": {
"Branch": null,
"Position": null,
"Id": null,
"FirstName": null,
"LastName": null,
"ParentName": null,
"Gender": null,
"Image": null,
"LoginStatusId": 0,
"EmployeeStatus": 0,
"CompanyName": null,
"IsSubcontractor": false
},
"KeyResults": [
{
"Id": 5032,
"Title": "asdf1",
"OverallStatus": 2,
"MonthKeyResults": [
{
"Id": 12484,
"Month": 9,
"Status": 3,
"Progress": "REaplace1"
},
{
"Id": 12483,
"Month": 8,
"Status": 3,
"Progress": "sadf4"
},
{
"Id": 12482,
"Month": 7,
"Status": 1,
"Progress": "On Track1"
}
]
},
{
"Id": 5033,
"Title": "asdf2",
"OverallStatus": 1,
"MonthKeyResults": [
{
"Id": 12485,
"Month": 7,
"Status": 2,
"Progress": "Recovery2"
},
{
"Id": 12487,
"Month": 9,
"Status": 2,
"Progress": "asdfreas"
},
{
"Id": 12486,
"Month": 8,
"Status": 1,
"Progress": "asdf5"
}
]
},
{
"Id": 5034,
"Title": "asdf3",
"OverallStatus": 2,
"MonthKeyResults": [
{
"Id": 12490,
"Month": 9,
"Status": 1,
"Progress": "asdafa"
},
{
"Id": 12489,
"Month": 8,
"Status": 2,
"Progress": "asdf6"
},
{
"Id": 12488,
"Month": 7,
"Status": 3,
"Progress": "Replace3"
}
]
}
]
}
]
Precisely I want stream to return MonthyKeyResult object with a specific id
Atm I am here
public static MonthKeyResults getOkrMonthlyProgressById(PageItems okr, Integer monthlyProgressId){
//here i get KeyResults object list
List<KeyResults> keyResult = okr.getKeyResults().stream().collect(Collectors.toList());
//and now I am trying to get all MonthKeyResults
//objects but I not doing it right
List<MonthKeyResults> monthKeyResults = keyResult.stream().
filter(monthKeyResult -> monthKeyResult.
getMonthKeyResults().
stream().collect(Collectors.toList()));
//and then I am thinking of going trough the monthKeyResults
//list with stream and finding Id I need and returning that
//whole object with something like this
MonthKeyResults mKeyResults = monthKeyResults.stream().filter(id -> id.getId().
equals(monthlyProgressId)).findAny().orElse(null);
return mKeyResult
}
I got one more question
I've separated getting the final object as you see in 3 streams, is it possible to get it in one go or you need to separate this objects like this and go trough them separately?
Probably you're looking for something like:
return okr.getKeyResults().stream()
.flatMap(keyResult -> keyResult.getMonthKeyResults().stream())
.filter(monthKeyResult -> monthKeyResult.getId().equals(monthlyProgressId))
.findAny()
.orElse(null);
Edit: fixed typo.

I want to skip some of the keys from the expected JSON file for comparison with the JSON response

I am new to coding and learning Rest Assured
I have saved a JSON file "expectedResponse.json" with content as:
[
{
"id": 1,
"name": "Resident Evil 4",
"releaseDate": "2005-10-01",
"reviewScore": 85,
"category": "Shooter",
"rating": "Universal"
},
{
"id": 2,
"name": "Gran Turismo 3",
"releaseDate": "2001-03-10",
"reviewScore": 91,
"category": "Driving",
"rating": "Universal"
},
{
"id": 3,
"name": "Tetris",
"releaseDate": "1984-06-25",
"reviewScore": 88,
"category": "Puzzle",
"rating": "Universal"
},
{
"id": 4,
"name": "Super Mario 64",
"releaseDate": "1996-10-20",
"reviewScore": 90,
"category": "Platform",
"rating": "Universal"
},
{
"id": 5,
"name": "The Legend of Zelda: Ocarina of Time",
"releaseDate": "1998-12-10",
"reviewScore": 93,
"category": "Adventure",
"rating": "PG-13"
},
{
"id": 6,
"name": "Doom",
"releaseDate": "1993-02-18",
"reviewScore": 81,
"category": "Shooter",
"rating": "Mature"
},
{
"id": 7,
"name": "Minecraft",
"releaseDate": "2011-12-05",
"reviewScore": 77,
"category": "Puzzle",
"rating": "Universal"
},
{
"id": 8,
"name": "SimCity 2000",
"releaseDate": "1994-09-11",
"reviewScore": 88,
"category": "Strategy",
"rating": "Universal"
},
{
"id": 9,
"name": "Final Fantasy VII",
"releaseDate": "1997-08-20",
"reviewScore": 97,
"category": "RPG",
"rating": "PG-13"
},
{
"id": 10,
"name": "Grand Theft Auto III",
"releaseDate": "2001-04-23",
"reviewScore": 90,
"category": "Driving",
"rating": "Mature"
}
]
However I want to skip some keys like "releaseDate" from comparison with the response as the date field can sometimes have a different format like "2021-03-13T20:22:49.935Z" (just an example) in response.
Currently I am able to assert the response and Expected JSON file with help of following method:=
public static String readFile(String className, String fileName) throws IOException
{
String content = new String(Files.readAllBytes(Paths.get(System.getProperty("user.dir")+"\\src\\test\\java\\TestData\\"+className+"\\data\\"+fileName)),StandardCharsets.UTF_8);
return content;
}
public static void responseAssertionWithFile(Response response, String className , String expResponseFile) throws ParseException, IOException
{
JSONParser jsonParser = new JSONParser();
JSONArray respArray = (JSONArray) jsonParser.parse(response.asString());
JSONArray expjsonArray = (JSONArray) jsonParser.parse(readFile(className,expResponseFile));
Assert.assertEquals(respArray.size(), expjsonArray.size());
#SuppressWarnings("unchecked")
Iterator<JSONObject> respIterator = respArray.iterator();
#SuppressWarnings("unchecked")
Iterator<JSONObject> expIterator = expjsonArray.iterator();
while(respIterator.hasNext() && expIterator.hasNext())
{
Assert.assertEquals(respIterator.next(), expIterator.next());
}
}
Override your assertEquals method and exclude the keys you dont want or include only the keys you want, whatever makes more sense in your usecase.
Something like:
public Boolean asserEquals(JSONObject obj1, JSONObject obj2){
String[] keysToExclude = {"releaseDate","whatever"};
for(String key : obj1){
if(!keysToExclude.contains(key) && obj1.get(key)!==obj2.get(key)){
return false;
}
}
return true;
}
This is probably not working Java code. I switched languages so much lately I am gettin them all mixed up. Lets call it pseudocode.
UPDATE:
Real Java code with json-simple
public Boolean assertEquals(JSONObject obj1, JSONObject obj2){
String[] keysToExclude = {"releaseDate","whatever"};
Iterator<String> keyIter = obj1.keySet().iterator();
while(keyIter.hasNext()) {
String key = keyIter.next();
if(!contains(keysToExclude,key) && !obj1.get(key).equals(obj2.get(key))) {
return false;
}
}
retrun true;
}
Oh and you will have to implement the contains function yourself. Here is a pointer: How do I determine whether an array contains a particular value in Java?.

Get value from a object

my collection contains documents like this:
{
"_id": ObjectId("585a7886e4b06aec5d1d1639"),
"name": "somename",
"owner": "someowner",
"slots": 50,
"gold": 0,
"tag": "sometext",
"motd": "sometext",
"purchases": [],
"members": {
"membername1": {
"rank": 2
},
"membername2": {
"rank": 5
},
"membername3": {
"rank": 3
}
}
}
I need to get int value from "members.membername.rank".
how do I get this value, knowing only membername?
The following code excludes the document's ID and gets only the rank for memername1
List<Document> pipeline = Arrays.asList(new Document("$project", new Document("rank", "$members.membername1.rank").append("_id", false)));
return ApiResponse.withBody(coll.aggregate(pipeline).first().getInteger("rank"));

How do I get sum of a field in solr 4.8

This is my response data:
"response": {
"numFound": 2,
"start": 0,
"docs": [
{
"total_amount": 10,
"id": "2"
},
{
"total_amount": 10,
"id": "1"
}
]
}
I want to get sum of total_amount. I tried facet query also. But I did't get sum. I got some blog on this but that is for solr 5.1. http://yonik.com/solr-facet-functions/
You can use the stats functionality to get this information. Just put the followed parameters in your query:
stats=true&stats.field=total_amount
Your response will be like that:
"response": {
"numFound": 2,
"start": 0,
"docs": [
{
"id": "1",
"total_amount": 15
},
{
"id": "2",
"total_amount": 12
}
]
},
"stats": {
"stats_fields": {
"total_amount": {
"min": 12,
"max": 15,
"count": 2,
"missing": 0,
"sum": 27,
"sumOfSquares": 369,
"mean": 13.5,
"stddev": 2.1213203435596424,
"facets": {}
}
}
Note that you have lots of information around the total_amount field including the sum.

Categories

Resources