构建有序 JSON 字符串(GSON 库)

Posted

技术标签:

【中文标题】构建有序 JSON 字符串(GSON 库)【英文标题】:Building ordered JSON string (GSON library) 【发布时间】:2021-12-25 20:46:32 【问题描述】:

下面是我的 JSON 应该是什么样子的一个简单示例。该对象具有名字和姓氏的字符串值、年龄的数字值和电话号码对象的数组值。


    "firstName": "John",
    "lastName": "Smith",
    "age": 25,
    "phoneNumbers": [
        
            "type": "home",
            "number": "212 555-1234"
        ,
        
            "type": "fax",
            "number": "646 555-4567" 
        
    ] 


这是我的代码:

        // creating JSONObject
        JSONObject jsonObj = new JSONObject();

        // putting data to JSONObject
        jsonObj.put("firstName", "John");
        jsonObj.put("lastName", "Smith");
        jsonObj.put("age", 25);

        // for phone numbers, first create JSONArray
        JSONArray jsonArr = new JSONArray();

        //  create LinkedHashMap
        Map<String,String> map = new LinkedHashMap<String, String>();

        map.put("type", "home");
        map.put("number", "212 555-1234");

        // adding map to list
        jsonArr.put(map);

        map.put("type", "fax");
        map.put("number", "212 555-1234");

        // adding map to list
        jsonArr.put(map);

        // putting phoneNumbers to JSONObject
        jsonObj.put("phoneNumbers", jsonArr);

        // Instantiate a new Gson instance.
        Gson gson = new Gson();

        // writing JSON to file:"JSONExample.json" in cwd
        String json = gson.toJson(jsonObj);

这就是我得到的:


"map":

"firstName":"John",
"lastName":"Smith",
"age":25,
"phoneNumbers":

"myArrayList":
[

"map":
       
        "type":"home",
        "number":"212 555-1234"
       
,

"map":
         
       "type":"fax",
       "number":"212 555-1234"
       

]



如何去除 JSON 字符串中的“myArrayList”和“map”?

更新 我更改了代码的最后一部分:

// writing JSON to file:"JSONExample.json" in cwd
        String json = jsonObj.toString();

而且它有效。但是当我像这样将“firstName”修改为“first”时:

// putting data to JSONObject
        jsonObj.put("first", "John");
        jsonObj.put("last", "Smith");
        jsonObj.put("age", 25);

我的字符串很乱,这很奇怪。

"last":"Smith","first":"John","age":25,"phoneNumbers":["type":"home","number":"212 555-1234","type":"fax","number":"212 555-1234"]

我认为 GSON 库保持字符串有序。

【问题讨论】:

你为什么不直接String json = jsonObj.toString() 效果很好。 好的,当我对代码进行少量更改时,这很奇怪。例如,如果我将“firstName”:“John”更改为“first”:“John”,我将得到无序字符串。你知道它有什么问题吗? JSONObject 是名称/值对的无序集合。 只要你混合库得到意想不到的结果,你试图做的事情就没有多大意义。 Gson 中没有像 JSONObject 这样的东西:Gson 类使用不同的命名,如 JsonObject。接下来,org.json.JSONObject 似乎遵循 JSON 规范,该规范通过使用 HashMap(至少对于我正在查看的实现)定义无序的 JSON 对象(如上所述)。另一方面,Gson 使用插入定义的顺序和链接哈希映射的自定义实现来保留插入顺序。 【参考方案1】:

尝试使用elegant-json。这个库默认保存元素的顺序。 这个 JSON:


    "firstName": "John",
    "lastName": "Smith",
    "age": 25,
    "phoneNumbers": [
        
            "type": "home",
            "number": "212 555-1234"
        ,
        
            "type": "fax",
            "number": "646 555-4567" 
        
    ] 

可以通过以下代码进行:

   new JsonObject()
       .add("firstName", new JsonString("John"))
       .add("lastName", new JsonString("Smith"))
       .add("age", new JsonInt(25))
       .add(
          "phoneNumbers", 
           new JsonArray()
               .add(
                   new JsonObject()
                       .add("type", new JsonString("home"))
                       .add("number", new JsonString("212 555-1234"))
               )
               .add(
                   new JsonObject()
                       .add("type", new JsonString("home"))
                       .add("number", new JsonString("212 555-1234"))
               )
       ).toJson();

注意:根据定义,JSON 没有排序。所以尽量不要依赖元素的顺序

【讨论】:

以上是关于构建有序 JSON 字符串(GSON 库)的主要内容,如果未能解决你的问题,请参考以下文章

75JSON 解析库---FastJson, Gson

使用google-gson类库解析json文件

Gson解析复杂JSON字符串的两种方式

Android Studio 中的 Gson 库

如何反序列化包含 GSON 库生成的 LocalDate 字段的 JSON

GSON - 从字符串中获取 JSON 值