Merging Two JSON Documents Using Jackson

Merging Two JSON Documents Using Jackson

One way is to use ObjectReader like so:

MyBean defaults = objectMapper.readValue(defaultJson, MyBean.class);
ObjectReader updater = objectMapper.readerForUpdating(defaults);
MyBean merged = updater.readValue(overridesJson);

which will combine data from two sources. This only makes a shallow copy, i.e. does not do recursive merge on contained objects.

Otherwise you may need to just read JSON as a tree (JsonNode), loop over contents and merge manually. This often makes sense anyway since rules of merging are not trivial, and everyone has their own ideas of how merging should work.

EDIT: (03-Apr-2017)

As per @Fernando Correia's comment, there is actually a new feature added in upcoming Jackson 2.9 (to be released in April or May 2017) that does allow deep merging, finally.

Merge several json objects Java with jackson

You could produce a new object and iterate over the fields in your existing data objects to assign them to the new object.

This existing answer shows how to merge objects by iterating over their fields. It performs a deeper-level merge, but to simply merge top-level keys you might do something like this for each data object to put their fields into a single ObjectNode:

ObjectNode merged = objectMapper.createObjectNode();
for (String name: execution.getVariableNames()) {
JsonNode data = objectMapper.readTree(execution.getVariable(name).toString());
data.fields()
.forEachRemaining(f -> merged.putIfAbsent(f.getKey(), f.getValue()));
}

(The forEachRemaining line is the relevant one to add keys from one object to another in this case.)

How to do deep merge JSON in jackson 2?

At this point, you will have to do that manually by traversing JSON trees (JsonNode) yourself, updating properties. There may be extension libraries that build on Jackson that provide support for this, but core Jackson databind only has "shallow" merge of single (root JSON Object) level.

How to merge two json Strings into one in java

Here is the code which recursively merges two jsons. This outputs as excepted:
NOTE: This is deep merge, not shallow merge ( similar concept used for shall vs deep copy)

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

Merge (Concat) Multiple JSONObjects in Java

If you want a new object with two keys, Object1 and Object2, you can do:

JSONObject Obj1 = (JSONObject) jso1.get("Object1");
JSONObject Obj2 = (JSONObject) jso2.get("Object2");
JSONObject combined = new JSONObject();
combined.put("Object1", Obj1);
combined.put("Object2", Obj2);

If you want to merge them, so e.g. a top level object has 5 keys (Stringkey1, ArrayKey, StringKey2, StringKey3, StringKey4), I think you have to do that manually:

JSONObject merged = new JSONObject(Obj1, JSONObject.getNames(Obj1));
for(String key : JSONObject.getNames(Obj2))
{
merged.put(key, Obj2.get(key));
}

This would be a lot easier if JSONObject implemented Map, and supported putAll.

How to efficiently merge two JSON Strings based on a common key

JsonNode json1 = objectMapper.readTree(jsonOneString);
JsonNode json2 = objectMapper.readTree(jsonTwoString);
for (JsonNode json1elem : json1) {
for (JsonNode json2elem : json2) {
if (json1elem.get("title").equals(json2elem.get("title"))) {
((ObjectNode) json1elem).setAll((ObjectNode) json2elem);
break;
}
}
}
System.out.println(json1.toPrettyString());


Related Topics



Leave a reply



Submit