Map JSONObject to Java Object - java

I'm developing an Android application that needs to contact an API REST that gives a JSON structured as follow
{
"TEST1": [
{
"delegate": true,
"unit": "mmHg",
"code": "DIA",
"read": true,
"write": true
},
{
"delegate": true,
"unit": "mmHg",
"code": "SYS",
"read": true,
"write": true
}
],
"TEST2": [
{
"delegate": true,
"unit": "°C",
"code": "TEMPERATURE",
"read": true,
"write": true
}
]}
Now I thought to map the inner object in the array as a simple Java Object (e.g MyObject) with 5 fields, but how can I map the entire Object when I do the retrofit call? I don't think that
List<List<MyObject>>
would fit this case since I need to know the keys ("TEST1", "TEST2").
Any help will be appreciated

Maybe the best choice is to map the response in a JsonObject and then take the values with
JsonArray test1 = jsonObject.getAsJsonArray("TEST1");
you could use a counter based on the response's length to make it more dynamic like:
int testCounter = 0;
JsonArray test1 = jsonObject.getAsJsonArray("TEST");
inside a loop of course

Related

Getting items from JsonArray dynamically no matter what is the type using GSON

I got this JsonArray:
"jokes": [
{
"description": "Knock Knock joke of the day!",
"language": "en",
"background": "",
"category": "knock-knock",
"date": "2019-12-02",
"joke": {
"title": "Knock Knock - Raoul who?",
"lang": "en",
"length": "64",
"clean": "1",
"racial": "0",
"id": "GcLEyRMil3Od8VaaNtGo5QeF",
"text": "Knock Knock\r\nWho's there?\r\nRaoul!\r\nRaoul who?\r\nRaoul of law!\r\n\r\n"
}
}
],
"copyright": "2019-20 https://jokes.one"
}
}
I want to be able to retrieve any item from the json array with no importance for the data type ,
for example if I want to get JsonObject joke I implemented this function:
public static JsonObject getJsonObjectFromJsonArray(int index, String fieldName, JsonArray jsonArray) {
return jsonArray.get(index).getAsJsonObject().get(fieldName).getAsJsonObject();
}
and if I want to retrieve json element which is string I implmeneted this function:
public static String getItemStringFromJsonArray(int index, String fieldName, JsonArray jsonArray){
return jsonArray.get(index).getAsJsonObject().get(fieldName).getAsString();
}
those two last methods looks the same but return different data types , how can I make it generic?
No pro solution could be set the variable type as object. Other solution it is if the value has some common found, you can set a parent class and use it as mayor class when defining. Or (pro solution for me) use Java 11 and define them as var.

RestAssured JsonPath: How to filter json objects from json

I'm trying to take an array of objects from json file and i have an issue.
path.get("wgcTournaments.items")
What path i should use to get all items(item0, item1, item2 ...) in items?
Can you please give me an advice how to do it.
Json example
{
"wgcTournaments": {
"items": {
"jcr:primaryType": "nt:unstructured",
"item0": {
"jcr:primaryType": "nt:unstructured",
"test": "test",
"test1": "test1"
},
"item1": {
"jcr:primaryType": "nt:unstructured",
"test": "test",
"test1": "test1"
},
"item2": {
"jcr:primaryType": "nt:unstructured",
"test": "test",
"test1": "test1"
},
"item3": {
"jcr:primaryType": "nt:unstructured",
"test": "test",
"test1": "test1"
}
}
}
}
The best way to filter item from items object but i don't understand how to do it with json path.
Finally i found a solution for my question.
If you want to get item from items you need to use this one json Path
path.getObject("wgcTournaments.items*.
find{it.key.startsWith('item')}.value",ItemClass[].class);
Note:
it was RestAssured and he uses Gpath more details you can find here
http://docs.groovy-lang.org/latest/html/documentation/#_gpath
You are trying to deserialize an object into an array of objects. Either your code or your JSON (most likely) is wrong.
If you want to deserialize items as an array, your JSON should be the following:
{
"wgcTournaments": {
"items": [
{
"jcr:primaryType": "nt:unstructured",
"item0": {},
"item1": {},
"item2": {},
"item3": {}
}
]
}
}
Otherwise, if your JSON is correct, you should deserialize your JSON using the following line:
path.getObject("wgcTournaments.items", MyClass.class)
EDIT: After your edit, this seems to be what you want:
If your JSON in correct and you indeed want an array, I assume that each itemX is a the key and {} the corresponding value. In this case, you have to know that you cannot have an associative array in JSON, you should use a custom solution to deserialize it, because your associative array will be converted into an object.

parsing json using Gson which has objects with same field name

I have a json file which has following structure:
{
"Otions": true
"Plastic": ""
"Houses": {
7: {
"name": "Akash Bhawan"
"MemBers": 3
"children": 1
}-
8: {
"name": "Ashiyana"
"memBers": 4
"children": 2
}-
9: {
"name": "Faruks Nest"
"memBers": 5
"children": 1
}-
The objects inside Houses are variable and can increase or decrease accordingly and also change names.
How ever the fieds "name", "members", "children" are the only fields and will always be there
i am using gson to parse
#SerializedName("Otions")
private String Options;
#SerializedName("Plastic")
private String plastics;
#SerializedName("Houses")
private Houses houses;
i want to know if there is a way we can i can store differently named objects in a hashtable or some other way?
If you can't change the structure then you have to make house as Hashmap of int to object. For Example:-
HashMap<int, Object> House;
And that object will have elements like name, memBers, details.
Houses should be a map like this.
private HashMap houses.
Since the 3: indicates an index-structure. Gson will create the nested objects as needed.
Please make "house" as bunch of array instead of objects.
{
"Options": true,
"Plastics": "",
"house": [{
"name": "Akash Bhawan",
"MemBers": 3,
"children": 1
}, {
"name": "Ashiyana",
"memBers": 4,
"children": 2
}, {
"name": "Faruks Nest",
"memBers": 5,
"children": 1
}]
}
You should do something like (as said in my comment):
JSONObject jsonHouses = jsonObject.getJSONObject("Houses");
Iterator<String> keys = jsonHouses.keys(); //this will be array of "7", "8", "9"
if (keys.hasNext()) {
JSONObject singleHouseObject = jsonHouses.getJSONObject(keys.next());
//now do whatever you want to do with singleHouseObject.
//this is the object which has "name", "MemBers", "children"
}

Retrieve a JsonArray that is nested in a changing JSON structure/hierarchy with GSON

I have a situation where I want to retrieve an array from JSON output. The array and its respective members never change. However, the hierarchy of the JSON output that contains the array does change periodically (beyond my control). I am struggling to figure out how to reliably extract the array without knowing the structure of the JSON hierarchy.
Example:
In JSON output #1 we have a bunch of objects with a sailors array nested snuggly in between:
{
"eat": "grub",
"drink": "rum",
"sailors": [
{
"firstName": "John",
"lastName": "Doe"
},
{
"firstName": "Anna",
"lastName": "Smith"
},
{
"firstName": "Peter",
"lastName": "Jones"
}
]
}
In JSON output #2 we have the same sailors array but its located in a different part of the hierarchy:
{
"eat": "grub",
"drink": "rum",
"boats": [
{
"name": "blackpearl"
},
{
"name": "batavia",
"crew": [
{
"name": "captain"
},
{
"name": "deckswab",
"anotherObject": {
"sailors": [
{
"firstName": "John",
"lastName": "Doe"
},
{
"firstName": "Anna",
"lastName": "Smith"
},
{
"firstName": "Peter",
"lastName": "Jones"
}
]
}
}
]
}
]
}
In both cases I want to end up with a Gson JsonArray of the sailors array.
JsonParser parser = new JsonParser();
JsonObject root = parser.parse(json).getAsJsonObject();
JsonArray sailors = root.get("sailors").getAsJsonArray();
The above code works fine for the JSON #1 output. I know that I can rewrite it for JSON output #2 by stringing together a bunch of get and getAsJsonObject/Array methods..
However, I’m not sure how to adapt it so that it will always find the array no matter where it is located in the hierarchy without have to re-write the code each time. This is important for me since the JSON output will likely change again the future and I would like my code to be a little bit more durable so that I do not have to re-write or update it whenever the JSON hierarchy changes again.
Please help!
You may want to use recursion and do this manually (using org.json). You may also use Gson or Jackson to read the tree from the JSON string.
You should have a getSailorsArray(String json) method that returns an array of all sailors.
To do this recursively, create methods to read a JSONArray, read a JSONObject and read a value. Each method will accept an object as argument. Check if the type of object is a JSONArray or a JSONObject or a value and call the appropriate recursive method. If it is an array, you may call the getJsonObject method in loop.
Put in your logic to check for the sailors key, and return the array when you encounter it. There, you have it!

comparing 2 json effectively

I have a json lets say json 1
[
{
"id": "123",
"testname": "test123",
"name": "John Doe",
"active": true,
"type": "test6"
}
{
"id": "456",
"testname": "test564",
"name": "Ship Therasus",
"active": true,
"type": "test7"
}
.... some 100 entries
]
and json 2 some like below
[
{
"id": "123",
"country": "USA",
"state": "KA",
"age": 24,
"group": "g1"
}
{
"id": "456",
"country": "UK",
"state": "MA",
"age": 28,
"group": "G2"
}
...... 100 entries
]
Now Id is the constant thing between json1 and json2 I want to make a resultant json something like below lets call json3.I want to match the id and get country and state from json2 and append to json 1.I am not looking for code but if i do brute force it takes 100* 100 and hence performance issues. is there any better way to handle this in less complexity?
[
{
"id": "123",
"testname": "test123",
"name": "John Doe",
"active": true,
"type": "test6",
"country":"USA",
"state":"KA"
}
{
"id": "456",
"testname": "test564",
"name": "Ship Therasus",
"active": true,
"type": "test7",
"country":"UK",
"state":"MA"
}
]
The best approach to this problem is O(size(json1 || json2)), because inherently you will have to go through atleast one of the json lists fully to loop through all of the IDs. If you have a constant time lookup (like a hashmap, keyed by the ID), you will be able to pull the information about that specific ID. Honestly I'm not familiar enough with json to suggest a data structure to use, but I know in Java, hashmaps are a frequently used constant time lookup. The best approach would be:
Loop through one json list
Pull out the ID from each entry in this list
Look up the information from the other json list using the same ID
Combine all the information in a resulting json list
Although this answer is somewhat vague, I hope it helps.
Without making any assumptions, I can't think of any way to avoid the O(n^2) complexity based on the given information.
However, if your arrays were already sorted by the object id, you could speed it up by iterating over the array.
var json3 = [];
for(var i = 0; i < json1.length; i++) {
json3.push($.extend({}, json1[i], json2[i]));
}
If you have control over the data structure, an object that is keyed by the id would be much easier to work with than an array:
e.g.
json1 = {
"123": {"testname": "test123", ...},"456": {...}
}
Then your code would simply
var json3 = {};
for(var id in json1) {
json3[id] = $.extend({}, json1[id], json2[id]));
}

Categories