Consume complex api data using retrofit [duplicate] - java

This question already has answers here:
How do I parse JSON in Android? [duplicate]
(3 answers)
Closed 4 years ago.
{"data":
{
"item1": {
"name" : "Box"
"price" : "50"
},
"item2": {
"name" : "Bottle"
"price" : "250"
}, .....
"item20": {
"name" : "Pen"
"price" : "100"
}
}}
This is my API structure. I cannot create separate POJO classes for 20 items as it is not efficient . What is the best way to fetch the name and price of every item and set them to a recycler view?

You will have to change format of your JSON in order to parse it properly. In addition you forgot to put commas after the "name" value.
Option 1:
{
"data":[
{
"name":"Box",
"price":"50"
},
{
"name":"Bottle",
"price":"250"
},
{
"name":"Pen",
"price":"100"
}
]
}
Option 2:
{
"data":{
"item1":{
"name":"Box",
"price":"50"
},
"item2":{
"name":"Bottle",
"price":"250"
},
"item20":{
"name":"Pen",
"price":"100"
}
}
}
Option 1 is the better choice, since you will be able to represent "data" as an array or a list in android (e.g. ArrayList<Data>).
In general i would suggest you to use a parsing library like GSON

Simple, just use GSON to create an object with SerializableNames to hold the json.
Then simply make an arrayList of your gson compatible object.
The rest is just common adapter interactions.
Example of an API return json object that I use. It must match your json structure.
The example is in Kotlin, but it's the same thing for handling json api response.

Create a simple class then do as mentioned in the image
after clicking the Generate option you see the GsonFromat click then a Box will Prompt , If you are unable to see the GsonFormat then download the GsonFormat plugin. This is the simplest way by which you can easily create Pojo class.
put this into the box and click ok it will automatically create the class for you and you can fetch the data.
{
"data":[
{
"name":"Box",
"price":"50"
},
{
"name":"Bottle",
"price":"250"
},
{
"name":"Pen",
"price":"100"
}
]
}

Related

How can I dynamically find the end of an object array inside of a JSON response using GSON?

I am working with a given JSON response. The API I'm using provides responses like such:
{
"data":[
{
"sample-value": "sample"
}
{
"sample-value": "sample"
}
{
"sample-value": "sample"
}
{
"sample-value": "sample"
}
],
"meta": {
"current-page": 1,
"next-page": 2,
"prev-page": null,
"total-pages": 5,
"total-count": 4338,
"filters": {}
},
"links": {
"self": "linktothisquery",
"next": "linktonextquery",
"last": "linktolastpagequery"
}
}
As you can see, the response provided contains what I interpret to be 1 object array (size changes depending on what is being queried) and 2 objects. (data is the array, meta and links are the objects) I have ran into a situation where I need to run multiple requests in order to get the full amount of data required for my project. I'm attempting to get around this by iterating through requests, but due to the variance in response length per-request I cannot use the same logic to locate only the array in the response and thus end up with unexpected characters making GSON unable to parse. I'm currently doing this by using String.substring() and manually inputting the location inside of the response that I want GSON to parse. Basically, I want GSON to ONLY see the "data" array and ignore everything else. I have model classes in my project to serialize the data, but they are built around the objects inside of the afforementioned array and not the array itself.
Your posted JSON is invalid .In data array comma is missing in between two objects. It should be
{
"sample-value": "sample"
},
{
"sample-value": "sample"
}
Now if you just want the data array part you can manually parse it using JsonParser. It will be the easiest way to do it.
String json = "{\"data\":[{\"sample-value\":\"sample\"},{\"sample-value\":\"sample\"},{\"sample-value\":\"sample\"},{\"sample-value\":\"sample\"}],\"meta\":{\"current-page\":1,\"next-page\":2,\"prev-page\":null,\"total-pages\":5,\"total-count\":4338,\"filters\":{}},\"links\":{\"self\":\"linktothisquery\",\"next\":\"linktonextquery\",\"last\":\"linktolastpagequery\"}}";
JsonObject jsonObject = JsonParser.parseString(json).getAsJsonObject();
JsonArray jsonArray = jsonObject.get("data").getAsJsonArray();
jsonArray.forEach(System.out::println);
Output:
{"sample-value":"sample"}
{"sample-value":"sample"}
{"sample-value":"sample"}
{"sample-value":"sample"}

How to compare 2 json by ignoring some attributes and child element orders

I'm seeking for a java library which can give fine grain control on json comparision. (just like XMLUnit)
For example, I have below 2 json document:
Control:
{
"timestamp":1234567,
"items":[
{
"id":111,
"title":"Test Item 111"
},
{
"id":222,
"title":"Test Item 222"
}
]
}
Test:
{
"timestamp":7654321,
"items":[
{
"id":222,
"title":"Test Item 222"
},
{
"id":111,
"title":"Test Item 111"
},
{
"id":333,
"title":"Test Item 333"
}
]
}
I'd like to apply below semantics when comparing them:
Ignore 'timestamp'
When comparing 'items', please do head to head compare against 'id'
Any suggestions?
As point out in your tags you can use Jackson to convert the both json to a Java class.
You can override the equals method within the class with your desired condition.
After all just use equals function in your objects.
JsonUnit seems to help:
https://github.com/lukas-krecan/JsonUnit#options
for my case:
Configuration cfg = Configuration.empty().when(path("items"), then(Option.IGNORING_ARRAY_ORDER, Option.IGNORING_EXTRA_ARRAY_ITEMS)).when(path("timestamp"), thenIgnore());
Diff diff = Diff.create(control, test, "", "", cfg);
assertTrue(diff.similar());

JSONPath, How to write (create) nested element (Java)

I want to create a json file. I know json simple, but the JsonObject and JsonArray aren't fast enough for me. I want the same efficiency as yaml (for finding and writing values with path).
I want to write this example :
{
"test": {
"test1": 564,
"test2": "der",
"list": [
"tes4",
"test5"
]
},
"exList": [
"tes4",
"test5"
]
}
The question is how to write the json part with JsonPath ?
DocumentContext#add doesn't seems to work
DocumentContext#put needs strange args
With this sample code, I'm getting this error:
PathNotFoundException: Missing property in path $['test1']
(Sorry, I'm French.)
What do you mean strange arguments? You can do:
String path = "$"
String key = "newValue"
int value = 1
yourJson.put(path, key, value)

Parse a structured flattened json object to list of object

I am current have a Json like :
{
"data":{
"gatewayId":"asd",
"records":[
{
"ms":123,
"points":[
{
"sensorId":"asdasd",
"sensorType":"asdasd",
"batt" : 12,
"kw" : 2
},
{
"sensorId":"123",
"sensorType":"as123dasd",
"batt" : 12,
"kw" : 2
}
]
},
{
"ms":123123,
"points":[
{
"sensorId":"asdasd",
"sensorType":"asdasd",
"batt" : 12,
"kw" : 2
},
{
"sensorId":"123",
"sensorType":"as123dasd",
"batt" : 12,
"kw" : 2
}
]
}
]
},
"gatewayType":"Asdasd"
}
My purpose is to denormalise the object to the lowest level in Java
where the pojo is
class SimpleData {
private String gatewayId;
private String gatewayType;
private Long ms;
private String sensorType;
private Double batt;
private Long kw;
}
For what I did for now, I flatten the json to a list for string as below.
root.gatewayType="Asdasd"
root.data.gatewayId="asd"
root.data.records[0].ms=123
root.data.records[0].points[0].sensorId="asdasd"
root.data.records[0].points[0].sensorType="asdasd"
root.data.records[0].points[0].batt=12
root.data.records[0].points[0].kw=2
root.data.records[0].points[1].sensorId="123"
root.data.records[0].points[1].sensorType="as123dasd"
root.data.records[0].points[1].batt=12
root.data.records[0].points[1].kw=2
root.data.records[1].ms=123123
root.data.records[1].points[0].sensorId="asdasd"
root.data.records[1].points[0].sensorType="asdasd"
root.data.records[1].points[0].batt=12
root.data.records[1].points[0].kw=2
root.data.records[1].points[1].sensorId="123"
root.data.records[1].points[1].sensorType="as123dasd"
root.data.records[1].points[1].batt=12
root.data.records[1].points[1].kw=2
I am thinking is it any logic or library can parse the above list for string to list of SimpleData object?
Sorry, My question maybe not clear, I find a more simple way to solve the problem.
But I need a library to denormalize the json.
for example if the json is :
{
"a" : "1",
"b" : ["2", "3"]
}
will become
[
{
"a" : "1",
"b" : "2"
},
{
"a" : "1",
"b" : "3"
}
]
I believe the Gson library is what you are looking for. It provides simple methods to convert Json array to simple Java objects, and vice versa. Very handy, developed by Google.
I recommend fastjson, which is really fast and quite easy to use. In your case, you only need to define POJO in the structure as your JSON data and parse the JSON to Object. It's created by Alibaba.

org.json.simple - How to iterate through individual objects in a JSONArray, and arrays within the individual objects?

Using the org.json.simple library, how can I iterate through a JSONArray, processing its individual objects and arrays inside the individual objects?
I have found answers on how to do this for different JSON libraries but in my situation I am required to use org.json.simple.
Here is an example of what the JSONArray i need to process looks like:
[
{
"versions":[
{
"rocket_version":"3.3.0.0",
"pluginVersion":"1.0.1.0",
"uploaded":1429350563,
"changelog":"<ul>\r\n\t<li>ADDED: anti-suicide.imune permission<\/li>\r\n<\/ul>",
"url":"https:\/\/dev.rocket.foundation\/wp-content\/uploads\/AntiSuicide3.zip"
},
{
"rocket_version":"3.3.0.0",
"pluginVersion":"1.0.0.2",
"uploaded":1429283276,
"changelog":"<ul>\r\n\t<li>FIXED: hopefully fixed the allocated memory (needs testing)<\/li>\r\n<\/ul>",
"url":"https:\/\/dev.rocket.foundation\/wp-content\/uploads\/AntiSuicide2.zip"
},
{
"rocket_version":"3.3.0.0",
"pluginVersion":"1.0.0.1",
"uploaded":1429196020,
"changelog":"<ul>\r\n\t<li>FIXED: small exception every time someone suicide.<\/li>\r\n<\/ul>",
"url":"https:\/\/dev.rocket.foundation\/wp-content\/uploads\/AntiSuicide1.zip"
},
{
"rocket_version":"3.3.0.0",
"pluginVersion":"1.0.0.0",
"uploaded":1428923374,
"changelog":"",
"url":"https:\/\/dev.rocket.foundation\/wp-content\/uploads\/AntiSuicide.zip"
}
],
"author":"ApokPT",
"name":"Anti-Suicide",
"id":910,
"development_stage":"Release",
"headline":"Anti-Suicide relocation",
"url":"https:\/\/dev.rocket.foundation\/?post_type=rplugin&p=910"
},
{
"versions":[
{
"rocket_version":"3.3.0.0",
"pluginVersion":"1.0.0.0",
"uploaded":1429113571,
"changelog":"Updated needed libraries",
"url":"https:\/\/dev.rocket.foundation\/wp-content\/uploads\/ZaupWhitelist_1.0.0.02.zip"
},
{
"rocket_version":"3.3.0.0",
"pluginVersion":"1.0.0.0",
"uploaded":1429047352,
"changelog":"First release",
"url":"https:\/\/dev.rocket.foundation\/wp-content\/uploads\/ZaupWhitelist_1.0.0.01.zip"
}
],
"author":"Zamirathe",
"name":"Zaup Mysql Whitelist",
"id":929,
"development_stage":"Release",
"headline":"Whitelist in Mysql",
"url":"https:\/\/dev.rocket.foundation\/?post_type=rplugin&p=929"
},
{
"versions":[
{
"rocket_version":"3.3.0.0",
"pluginVersion":"1.3.5.0",
"uploaded":1429284290,
"changelog":"<ul>\r\n\t<li>FIXED: Possible memory leak (needs testing);<\/li>\r\n\t<li>FIXED: Reactivated strip on give kit;<\/li>\r\n\t<li>ADDED: Cooldown check for permission givekit.onjoin.<kitname><\/li>\r\n<\/ul>",
"url":"https:\/\/dev.rocket.foundation\/wp-content\/uploads\/GiveKit27.zip"
},
{
"rocket_version":"3.3.0.0",
"pluginVersion":"1.3.4.0",
"uploaded":1429192200,
"changelog":"<ul>\r\n\t<li>ADDED: givekit.onjoin.<kit name> permission<\/li>\r\n<\/ul>",
"url":"https:\/\/dev.rocket.foundation\/wp-content\/uploads\/GiveKit26.zip"
}
],
"author":"ApokPT",
"name":"Give Kit",
"id":858,
"development_stage":"Release",
"headline":"Give a Kit to another player or yourself",
"url":"https:\/\/dev.rocket.foundation\/?post_type=rplugin&p=858"
}
]
Each individual object in the whole array has a versions array and an "id" attribute. For each individual object, I need to:
Get the 'id' attribute's value
Iterate through each object in the 'versions' array and get the value of its attributes, such as 'url', 'changelog', 'pluginVersion', etc.
For each object in each versions array, I just need to call a method that accepts the id attribute, and the url/changelog/pluginVersion attributes.
How can I do this task in Java with the org.json.simple library?
Note: I need to use the org.json.simple library!
From the README file, it appears that parsing an object just gives you some classes that extend the basic java collection classes (org.json.simple.JSONObject inherits java.util.HashMap & org.json.simple.JSONArray inherits java.util.ArrayList) so you can use all the normal java methods. For example:
String s="[0,{\"1\":{\"2\":{\"3\":{\"4\":[5,{\"6\":7}]}}}}]";
Object obj=JSONValue.parse(s);
JSONArray array=(JSONArray)obj;
System.out.println(array.get(1));
JSONObject obj2=(JSONObject)array.get(1);
System.out.println(obj2.get("1"));
Result:
{"1":{"2":{"3":{"4":[5,{"6":7}]}}}}
{"2":{"3":{"4":[5,{"6":7}]}}}

Categories

Resources