Values get rearranged by JSONObject constructor - android

I have this:
String foo =
"options": {
"1",
"2",
"3",
"4",
"5",
"6",
"7",
"8",
"9",
}
But the JSONObject constructor rearranges the keys:
new JSONObject(foo).toString() =
"options": {
"6",
"3",
"7",
"2",
"5",
"1",
"4",
"8",
"9",
}
The new order is reproducible, meaning each execution results in the same (seemingly random) rearrangement.

That does not look like valid JSON to me. First, there is not {} or [] surrounding the entire string. Second, it looks like the data associated with options should be inside and array ([]) not be an object({}). If it was an array, the order would be preserved, whereas with the values just being declared as properties, there is no guarantee on their order.

In json sequence of the fields is not important, only their nesting.

Your example Strings are invalid JSON. You have a bare top-level field options, and no values for it's fields.
A javascript object, it's JSON representation, and in particular a JSONObject, do not guarantee an ordering of the fields.
From the JSONObject javadoc:
A JSONObject is an unordered collection of name/value pairs.
You can maintain an ordering by using an array. So if your data is or can be represented as an array - from your example it looks like an array - then the order of the elements will be maintained.

Related

How to use json in Android with Retrofit

In my application I want get some data from server and show this into list (recyclerview)!
I receive data from server such as below :
"data": {
"id": 1812286134,
"Cr": "85",
"BUN": "87",
"ALP": "75",
"ALT": "6",
"AST": "6",
"Chol": "55",
"HDL": "545",
"LDL": "45",
"TG": "4",
"created_at": "2022-10-30 16:05:50",
"updated_at": "2022-10-30 16:05:50"
}
UPDATE :
This data may update in some time, added new items or remove items by admins
I should show all of this items into recyclerview.
I know in above json data should list but has object.
But backend developer tells me convert all of this data to list with key value!
My question is can I convert this data to list and use all of items into list ?
How can I it?
Try to use Map<String,String> in your Response or whatever you used.
It will be something like this.
#GET
fun getCurrency():Response<DataResponse>
data class DataResponse(
val currencies:Map<String,String>
)

How to insert nested json into SQLite Flutter

I want to make a categories screen, the backend returns a nested json with 4 trees in total if I'm not mistaken,
example:
when I press the most general tree of the categories, I would like it to be displayed as a dropdown and there, put the children of this category, the ones that come in the json clearly, hope to explain myself well.
I have to fill these widgets, their text or titles with the text that comes clearly in the json, but I'm not going to be calling the endpoint every time I want to paint the titles, i have to save what comes in the json in the sqlite, and then extract from there the texts to put on categories screen ... how can I do this? I'm new, never build a structure like that, I have to do it with sqlite, but I wouldn't know how to start or how to build the tables, if I make a table, only the first tree of the categories will go, and the rest? the children of the nested json? Could someone guide me?
I leave you a piece of the json (for other reasons I can not put it complete) to put them a little more in context
{
"res": 0,
"categorias": [
{
"id": 1,
"name": "Bolsas",
"img": "hogar.png",
"titulo": 0,
"children": [
{
"id": 11,
"name": "Para llevar",
"img": "llevar.png",
"titulo": 0
},
{
"id": 12,
"name": "Para Conservar",
"img": "consrvar.png",
"titulo": 0
},
{
"id": 13,
"name": "Para Organizar",
"img": "organizar.png",
"titulo": 0
},
{
"id": 14,
"name": "Multipack",
"img": "multipack.png",
"titulo": 0
}
]
},
{
"id": 2,
"name": "Cuidado del aire",
"img": "aire.png",
"titulo": 0,
"children": [
{
"id": 21,
"name": "Instantaneo",
"img": "instantaneo.png",
"titulo": 0,
"children": [
{
"id": 211,
"name": "Aerosol",
"img": "llevar.png",
"titulo": 0
},
{
"id": 212,
"name": "Toque",
"img": "consrvar.png",
"titulo": 0
}
]
},
You have several option to work with json and sqlite:
Just put your json as string in row on table and then select as string and convert to json.
You can use similar approach from paragraph 1 bud with using sqlite's json extension. It adds possibility to select of update parts of json by special query syntax. To use sqlite with this extension u will need custom build of sqlite like sqlite-android (with have many other benefits).
You can crate separate sqlite table from each level fo json nesting (depends on your need of granularity). For example you can create table categorias with columsn(categorias_id, categorias_name, categorias_img, categorias_titulo), table categorias_childrens with columns(categorias_id, id, name, img, titulo, categorias_childrens_id).
In this case all rows of categorias_childrens table related with categorias.categorias_id contains categorias.categorias_id in categorias_childrens.categorias_id column. And all rows related with some of categorias_childrens row contains categorias_childrens.categorias_id in categorias_childrens.categorias_childrens_id column (situation when children.id.21 has childrens ).
Or u can combine approaches fro example: create table categorias with columsn(categorias_id, categorias_name, categorias_img, categorias_titulo, children) where column children will be contains string json value.

How to write and read contents containing complex json data?

friends:
I get a response from remote server as follows on Android:
{
"items": {
"persons": [
{
"id": "200120",
"name": "Bill"
},
{
"id": "200121",
"name": "Jim"
}
],
"tasks": [
{
"id": "001",
"name": "Fetch ten books",
"deadline": "5:30 p.m.",
"scores": "10"
},
{
"id": "002",
"name": "Fetch thirty books",
"deadline": "5:30 p.m.",
"scores": "30"
}
],
"intro": "This is a funny game."
},
"otherObj": []
}
And I want to save it to phones. I do not think it a good choice to save it into databases. However it read not fast if put the response to SharedPreferences file. Is there any other way?
No need to save this data into database as these value are dynamic and will change time to time.
In your Activity, call the API and get JSON as response and then parse this JSON and show it on device.
To store it on device u can use Singleton class also.
For JSON parser refer to http://www.tutorialspoint.com/android/android_json_parser.htm
You can first save your data into objects and at last into Object Array and then Save to database.(If your data is dynamic it is better you only deal with Object not database)
For saving to database you can use
db.beginTransaction();
for(object : ObjectArray){
db.dboperation();
}
db.setTransactionSuccessful();
db.endTransaction();

Jackson deserializing JSON into multiple POJOs

Hi I have following JSON
{
"code": 0,
"response": {
"userObject": {
"User": {
"id": "355660",
"first_name": "Dummy",
"last_name": "dummy",
"email": "dumb#email.com",
"birthday": "2012-05-07",
"created": "2012-08-21 06:41:05",
"modified": "2012-08-21 06:41:05",
"image_url": null,
},
"Location": {
"id": "273550",
"name": "New York City",
"asciiName": "New York City",
"lat": "40.714272",
"lon": "-74.005966",
"geoname_modified": "2011-11-08 00:00:00",
"timeZone": "America/New_York",
"countryName": "United States",
"state": "New York",
"created": "2012-07-12 12:11:01",
"modified": "2012-08-20 14:27:24"
}
}
}
}
I have two classes, one each for Location and User
I know that I can get the objects if I create nested class like
response
->UserObject
*User
*Location
But i don't want to create two extra classes for UserObject and response just for wrapping the two POJO's .
Is there any simpler way to do it??
I am using Jackson Parser with Spring for android
You can also do it in two steps, if you really want to avoid throw-away classes, like:
JsonNode tree = mapper.readTree(...);
User user = mapper.treeToValue(tree.path("response").path("userObject").get("User"), User.class);
Location loc = mapper.convertValue(tree.path("response").path("userObject").get("Location"), Location.class);
but yeah I might go with silly struct-classes instead:
static class Response {
public UserObject userObject;
}
static class UserObject {
public Location Location;
public User User;
}
since it really isn't much more code.
Rather than creating classes you could create arrays or use hashmap. Personally, I would just create the classes. I think that this give you more flexibility in your app, and will allow you to work with the objects with less hassle. I know it takes time to set them up, but once you do that, you can use ArrayList and you can parse the JSON quite a bit easier.

Android: Using GSON to parse a response with dynamic fields

I need to parse a JSON response regarding events in an agenda, of which a field is dynamic. This field changes depending on the month in which the event takes place.
Now I've been parsing data with GSON before, but these all had static fields so it was quite easy to create the necessary POJO's. But how would I do this with dynamic fields?
The response i need to parse is like so:
{
"Agenda/Future": {
"November 2011/0": [
{
"id": "5675",
"eventid": "",
"name": "testing testing 123",
"startdate": "nov 25",
"datecompute": "2011-11-25T08:00:00",
"group_month": "November 2011",
"flg_Data": "Database"
}
],
"February 2012/1": [
{
"id": "5681",
"eventid": "",
"name": "dfd",
"startdate": "feb 3",
"datecompute": "2012-02-03T12:00:00",
"group_month": "February 2012",
"flg_Data": "Database"
},
{
"id": "5679",
"eventid": "",
"name": "vfvd",
"startdate": "feb 17",
"datecompute": "2012-02-17T12:00:00",
"group_month": "February 2012",
"flg_Data": "Database"
}
],
"February 2013/2": [
{
"id": "5680",
"eventid": "",
"name": "df",
"startdate": "feb 14",
"datecompute": "2013-02-14T12:00:00",
"group_month": "February 2013",
"flg_Data": "Database"
}
],
"September 2013/3": [
{
"id": "5677",
"eventid": "",
"name": "fsdfsd",
"startdate": "sep 14",
"datecompute": "2013-09-14T12:00:00",
"group_month": "September 2013",
"flg_Data": "Database"
}
],
"November 2015/4": [
{
"id": "5676",
"eventid": "",
"name": "fsdfsd",
"startdate": "nov 13",
"datecompute": "2015-11-13T12:00:00",
"group_month": "November 2015",
"flg_Data": "Database"
}
]
}
}
As you can see, the object title regarding months is dynamic. Both the value at the end of the title, as well as the title itself change based on the actual month and position in the array of months.
From what I've seen on other questions here at SO, I will need to work with Maps.
But I'm not quite sure how I would go about doing so.
Let's say I create a POJO called Event for the individual events contained in the array of the months, what would my initialization look like?
Regards
I have tried Amir's suggestion by using Jackson with the default Map.
Sadly, this creates a Map with a size of 1. The entire JSON response gets parsed into a single object. Ofcourse, this is not what I want, since I need to get the data from the individual events.
Does anyone have a suggestion as to how I might be able to do that? Normally I'd figure out these things quite quickly but I can't wrap my head around this one due to the dynamic object naming.
I have eventually managed to crack this problem. I ended up using plain JSONObjects, which worked eventually.
The code I used to get it to work is as follows:
JSONObject jsonObject = new JSONObject(response);
JSONObject agenda = jsonObject.getJSONObject("Agenda/Future");
if (agenda != null) {
System.out.println(agenda.length());
JSONArray events = agenda.names();
if (events.length() > 0) {
System.out.println("At least its bigger then 0. It's: "
+ events.length());
for (int i = 0; i < events.length(); i++) {
System.out.println(events.get(i).toString());
JSONArray test = agenda.getJSONArray(events.get(i)
.toString());
if (test != null) {
JSONObject testt = test.getJSONObject(0);
if (testt != null) {
System.out.println(testt.getString("name"));
} else {
System.out.println("Still empty, Check again.");
}
}
}
}
} else {
System.out.println("Agenda is completely empty, try again.");
}
As you can see, this still contains test-names, but at least it works.
Thanks for the help everyone!
Since the month data are not valid java identifiers, you 'll probably have to use custom serialization with GSON. You're talking about using Map objects but if you are going to do that you may as well us the org.json objects like JSONObject which are basically built on maps/hashtables anyway.
If all your fields, as you have said, are dynamic then you can create a super set of all fields in a pojo. But that doesn't really help and I think the Map is the best solution. With GSON, you can do
Type type = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> map = gson.fromJson("{'key1':'123','key2':'456'}", type);
This will return a map of strings.
I haven't actually used GSON to do this before though. I have been very happy with Jackson lib and with that you can do
new ObjectMapper().readValue("...json...", Map.class)
The above will return a map of maps which is what you want.

Categories

Resources