如何在java中将两个json字符串合并为一个

9nvpjoqh  于 2023-01-06  发布在  Java
关注(0)|答案(4)|浏览(802)

如果我们已经给出了两个json类型的字符串,我们如何在java中将它们合并成一个json字符串?

e.g. 

    String json1 = {
        "glossary": {
            "title": "example glossary",
            "GlossDiv": {
                "title": "S"
            }
        }
    }

String json2 = {
        "glossary": {
            "title": "person name",
            "age":  "25"
        }
    }

应产生

String mergedJson = {
   "glossary": {
            "title": "example glossary",
            "GlossDiv": {
                "title": "S"
            },
            "age":  "25"
        }
}
y0u0uwnf

y0u0uwnf1#

下面的代码应该可以做到这一点,但需要做几个假设:

  • 您正在使用Jackson库(com.fasterxml.jackson.databind.ObjectMapper)的ObjectMapper来序列化/反序列化json
  • 合并时,json 1的字段将始终覆盖json 2
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> map1 = mapper.readValue("json1", Map.class);
Map<String, Object> map2 = mapper.readValue("json2", Map.class);
Map<String, Object> merged = new HashMap<String, Object>(map2);
merged.putAll(map1);
System.out.println(mapper.writeValueAsString(merged));
njthzxwz

njthzxwz2#

下面是递归合并两个json的代码,输出如下:注:这是深度合并,而不是浅合并(与shall和深度复制使用的概念相似)

private static JsonObject merge(JsonObject json1Obj, JsonObject json2Obj) {

        Set<Entry<String, JsonElement>> entrySet1 = json1Obj.entrySet();
        for (Entry<String, JsonElement> entry : entrySet1) {
            String key1 = entry.getKey();
            if (json2Obj.get(key1) != null) {
                JsonElement tempEle2 = json2Obj.get(key1);
                JsonElement tempEle1 = entry.getValue();
                if (tempEle2.isJsonObject() && tempEle1.isJsonObject()) {
                    JsonObject mergedObj = merge(tempEle1.getAsJsonObject(),
                            tempEle2.getAsJsonObject());
                    entry.setValue(mergedObj);
                }
            }
        }

        Set<Entry<String, JsonElement>> entrySet2 = json2Obj.entrySet();
        for (Entry<String, JsonElement> entry : entrySet2) {
            String key2 = entry.getKey();
            if (json1Obj.get(key2) == null) {
                json1Obj.add(key2, entry.getValue());
            }
        }
        return json1Obj;
    }
8i9zcol2

8i9zcol23#

考虑使用一个可以完成这项工作的库,如JSON Merge,可从Maven Central获得。
您只需一行代码就可以获得所需的结果(如果您之前已经加载了JSONObject,则可以忽略String声明):

String json1 = "{\n"
        + "        \"glossary\": {\n"
        + "            \"title\": \"example glossary\",\n"
        + "            \"GlossDiv\": {\n"
        + "                \"title\": \"S\"\n"
        + "            }\n"
        + "        }\n"
        + "    }";

String json2 = "{\n"
        + "        \"glossary\": {\n"
        + "            \"title\": \"person name\",\n"
        + "            \"age\":  \"25\"\n"
        + "        }\n"
        + "    }";

JSONObject result = new JsonMerger<>(JSONObject.class).merge(json2, json1);

**注意:**在发生键冲突的情况下,传递给merge方法的第一个JSON参数总是比第二个参数具有更高的优先级/重要性。

这个库也可以与Jackson、Gson和其他JSON提供程序一起使用。

lf5gs5x2

lf5gs5x24#

所以我已经迟到了,但是如果有人偶然发现这个,我想分享我的解决方案,你可以用com.fasterxml.jackson.core:jackson-databindObjectMapper.readerForUpdating()深度合并两个json字符串。
在这个场景中,您将两个Json作为String传入,并通过readerForUpdating(未经测试的代码)合并它们:

public String mergeJsonStrings(String json1, String json2) {
    ObjectMapper mapper = new ObjectMapper();
    ObjectReader reader = mapper.readerForUpdating(json1);
    String result = reader.readValue(json2);
    return result;
}

我用类似的代码将一个属性合并到一个已有的数据集中。在这个例子中,SomeProperties类包含一个hashmap,它保存了一个特定用户的属性。传入的propertiesString是一个单点分隔的属性,例如some.random.property=value。这个属性将被转换成一个JsonNodecom.fasterxml.jackson.dataformat:jackson-dataformat-properties

public SomeProperties mergeProperties(SomeProperties someProperties, String propertiesString) {
    JavaPropsMapper javaPropsMapper = new JavaPropsMapper();
    ObjectMapper objectMapper = new ObjectMapper();
    JsonNode jsonNode = javaPropsMapper.readTree(propertiesString);
    ObjectReader objectReader = mapper.readerForUpdating(someProperties.getProperties());
    HashMap<String, Object> mergedProperties = objectReader.readValue(jsonNode);
    someProperties.setProperties(mergedProperties);
    return someProperties;
}

在这两种情况下,传入objectReader.readValue()的所有内容都将覆盖现有密钥。

相关问题