将两个JSON合并到JSONObject而不是JSONArray

时间:2020-08-21 11:27:52

标签: java json

我需要找到一种方法来将两个(或多个)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: 更新了示例代码和预期的输出,以使图像更加清晰

1 个答案:

答案 0 :(得分:0)

我更喜欢并建议使用 Google 中的 Gson

最新版本是 2019年10月 2.8.6

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

始终检查 Maven Central信息库中的最新版本:


示例:

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;
}

参考: