Android Question Can JSON [library] generate json string with keys in order

Steve Kwok

Member
Licensed User
I was recently be worried by json string with keys not in order issue.
I am developing an android data collector which collect data inserting into sqlite table and finally generate json string for posting to web service.
The json string required by system (i.e. web service) is:

B4X:
{
    "scanid": "393190226115551C",
    "loc": "39",
    "staffid": "0123",
    "createdatetime": "2019/02/26 11:55:51",
    "uploaddatetime": "2019/02/26 11:58:03",
    "listdate": "2019/02/23",
    "closingdate": "2019/02/24",
    "stockregistryline": [
        {
            "entryno": 1,
            "scandate": "2019/02/26",
            "scantime": "11:56:35"
        },
        {
            "entryno": 2,
            "scandate": "2019/02/26",
            "scantime": "11:59:29"
        },
        {
            "entryno": 3,
            "scandate": "2019/02/26",
            "scantime": "12:00:05"
        }
    ]
}
However, when i use JSON [library] to generate the string become:
B4X:
{
    "stockregistryline": [
        {
            "scandate": "2019/02/26",
            "entryno": 1,
            "scantime": "11:56:35"
        },
        {
            "scandate": "2019/02/26",
            "entryno": 2,
            "scantime": "11:59:29"
        },
        {
            "scandate": "2019/02/26",
            "entryno": 3,
            "scantime": "12:00:05"
        }
    ],
    "closingdate": "2019/02/24",
    "scanid": "393190226115551C",
    "loc": "39",
    "listdate": "2019/02/23",
    "createdatetime": "2019/02/26 11:55:51",
    "staffid": "0123",
    "uploaddatetime": "2019/02/26 11:58:03"
}
The json generated is NOT in order.
Here is the codes I used in my project:
B4X:
Private Sub map2json3()
    Dim mapTest2 As Map : mapTest2.Initialize
    mapTest2.Put("scanid": "393190226115551C")
    mapTest2.Put("loc": "39")
    mapTest2.Put("staffid": "0123")
    mapTest2.Put("createdatetime": "2019/02/26 11:55:51")
    mapTest2.Put("uploaddatetime": "2019/02/26 11:58:03")
    mapTest2.Put("listdate": "2019/02/23")
    mapTest2.Put("closingdate": "2019/02/24")
    mapTest2.Put("stockregistryline": mapInList3)   
    Dim jGen As JSONGenerator
    Try
        jGen.Initialize(mapTest2)
        Log(jGen.ToString)
    Catch
        Log(LastException)
    End Try
End Sub

Private Sub mapInList3() As List
    Dim lstTest2 As List : lstTest2.Initialize   
    lstTest2.Add(CreateMap("entryno": 1, "scandate": "2019/02/26", "scantime": "11:56:35"))
    lstTest2.Add(CreateMap("entryno": 2, "scandate": "2019/02/26", "scantime": "11:59:29"))
    lstTest2.Add(CreateMap("entryno": 3, "scandate": "2019/02/26", "scantime": "12:00:05"))
    Return lstTest2
End Sub
What can i do to make resulting json string with keys in map insertion order?
 

Erel

Administrator
Staff member
Licensed User
It will be easier to read the logs with:
B4X:
Dim jGen As JSONGenerator
   jGen.Initialize(mapTest2)
   Log(jGen.ToPrettyString(4))
The output here is:
B4X:
** Activity (main) Create, isFirst = true **
{
    "scanid": "393190226115551C",
    "loc": "39",
    "staffid": "0123",
    "createdatetime": "2019\/02\/26 11:55:51",
    "uploaddatetime": "2019\/02\/26 11:58:03",
    "listdate": "2019\/02\/23",
    "closingdate": "2019\/02\/24",
    "stockregistryline": [
        {
            "entryno": 1,
            "scandate": "2019\/02\/26",
            "scantime": "11:56:35"
        },
        {
            "entryno": 2,
            "scandate": "2019\/02\/26",
            "scantime": "11:59:29"
        },
        {
            "entryno": 3,
            "scandate": "2019\/02\/26",
            "scantime": "12:00:05"
        }
    ]
}
** Activity (main) Resume **
What is your output?
 

prizemart

Member
Licensed User
Mine is


B4X:
** Activity (main) Resume **
{
    "stockregistryline": [
        {
            "scandate": "2019\/02\/26",
            "entryno": 1,
            "scantime": "11:56:35"
        },
        {
            "scandate": "2019\/02\/26",
            "entryno": 2,
            "scantime": "11:59:29"
        },
        {
            "scandate": "2019\/02\/26",
            "entryno": 3,
            "scantime": "12:00:05"
        }
    ],
    "closingdate": "2019\/02\/24",
    "scanid": "393190226115551C",
    "loc": "39",
    "listdate": "2019\/02\/23",
    "createdatetime": "2019\/02\/26 11:55:51",
    "staffid": "0123",
    "uploaddatetime": "2019\/02\/26 11:58:03"
}
** Activity (main) Pause, UserClosed = true **
 

Erel

Administrator
Staff member
Licensed User
I see the problem. JsonGenerator is based on the Android native Json SDK. In newer versions of Android the internal SDK preserves the order of items. This is not the case in older versions.

B4A Map does preserve the order. The "problem" here is in the native implementation. You will need to serialize the map yourself. Shouldn't be too difficult for specific cases.
 
Top