java—将两个JSON合并到jsonobject而不是jsonarray

9njqaruj  于 2021-07-08  发布在  Java
关注(0)|答案(1)|浏览(811)

我需要找到一种方法,如何将两个(或更多)json对象合并到一个没有json数组的json对象中。
下面是代码示例:

public static void mergeJSONs() {
    JSONObject jsonObject1 = new JSONObject("{\"1level1\":{\"1level2\":{\"1label1\":\"1value1\"}}}");
    JSONObject jsonObject2 = new JSONObject("{\"1level1\":{\"1level2\":{\"1label2\":\"1value2\"}}}");
    JSONObject jsonObject3 = new JSONObject("{\"2level1\":{\"2level2\":{\"2level3\":{\"2label1\":\"2value1\"}}}}");
    JSONObject jsonObject4 = new JSONObject("{\"2level1\":{\"2level2\":{\"2label2\":\"2value2\"}}}");

    JSONObject combined = new JSONObject();
    combined.put("strings", jsonObject1);
    combined.put("strings", jsonObject2);
    combined.put("strings", jsonObject3);
    combined.put("strings", jsonObject4);

    System.out.println(combined.toString());
}

此代码的输出:

{"strings":{"2level1":{"2level2":{"2label2":"2value2"}}}}

预期产量:

{
   "strings":{
      "1level1":{
         "1level2":{
            "1label1":"1value1",
            "1label2":"1value2"
         }
      },
      "2level1":{
         "2level2":{
            "2level3":{
               "2label1":"2value1"
            },
            "2label2":"2value2"
         }
      }
   }
}

或在一行中:

{"strings":{"1level1":{"1level2":{"1label1":"1value1","1label2":"1value2"}},"2level1":{"2level2":{"2level3":{"2label1":"2value1"},"2label2":"2value2"}}}}

问题是,我永远不会知道json对象的名称,以及这个json到底有多深,因为它将用于转换文件,所以我无法为此创建pojo。
目前我正在使用org.json库来实现这一点,但是如果有一种简单的方法可以在其他库中实现这一点的话,我也可以这样做。
图书馆:

<dependency>
    <groupId>org.json</groupId>
    <artifactId>json</artifactId>
    <version>20180813</version>
</dependency>

更新#1:这些对象只是提供了一个示例,实际上json会更大、更深。问题是,我永远不知道json中的键有多深,哪些键匹配。所以这里需要递归方法,它将遍历两个对象,直到有任何键匹配,并且其中一个对象不包含该键,然后所有嵌套对象都应合并到该对象中。
更新#2:更新示例代码和预期输出,以使图像更清晰

kmbjn2e3

kmbjn2e31#

我更喜欢并推荐使用谷歌的gson:
从2019年10月起,最新版本为2.8.6:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.6</version>
</dependency>

始终检查maven中央存储库的最新版本:
https://mvnrepository.com/artifact/com.google.code.gson/gson
例子:

public static void mergeJSONs() {
  String JSON1 = "{\"1level1\":{\"1level2\":{\"1label1\":\"1value1\"}}}";
  String JSON2 = "{\"1level1\":{\"1level2\":{\"1label2\":\"1value2\"}}}";
  String JSON3 = "{\"2level1\":{\"2level2\":{\"2level3\":{\"2label1\":\"2value1\"}}}}";
  String JSON4 = "{\"2level1\":{\"2level2\":{\"2label2\":\"2value2\"}}}";
  String finalJson = organizeJson(JSON1, JSON2, JSON3, JSON4);
  System.out.println(finalJson);
}

该方法可以接收json有效负载列表,添加根元素并合并:

public String organizeJson(String... jsonList) throws Exception {
    JsonObject jsonObj = null;
    Gson gson = new GsonBuilder().setPrettyPrinting().create();
    for (String json : jsonList) {
        if (jsonObj != null) {
            jsonObj = jsonMerge(jsonObj, gson.fromJson(json, JsonObject.class));
        } else {
            jsonObj = gson.fromJson(json, JsonObject.class);
        }
    }
    JsonObject jsonStringsRoot = new JsonObject();
    /* Add "strings" as root element */
    jsonStringsRoot.add("strings", jsonObj);
    return gson.toJson(jsonStringsRoot);
}

方法使用递归调用查找嵌套对象的最后一级(深度合并):

public static JsonObject jsonMerge(JsonObject jsonA, JsonObject jsonB) throws Exception {
    for (Map.Entry<String, JsonElement> sourceEntry : jsonA.entrySet()) {
        String key = sourceEntry.getKey();
        JsonElement value = sourceEntry.getValue();
        if (!jsonB.has(key)) {
            if (!value.isJsonNull()) {
                jsonB.add(key, value);
            }
        } else {
            if (!value.isJsonNull()) {
                if (value.isJsonObject()) {
                    jsonMerge(value.getAsJsonObject(), jsonB.get(key).getAsJsonObject());
                } else {
                    jsonB.add(key, value);
                }
            } else {
                jsonB.remove(key);
            }
        }
    }
    return jsonB;
}

参考文献:

https://stackoverflow.com/a/38757661/5626568

相关问题