エレルのおかげです。これはGsonバージョンです。
/**
* Merge "source" into "target". If fields have equal name, merge them recursively.
* Null values in source will remove the field from the target.
* Override target values with source values
* Keys not supplied in source will remain unchanged in target
*
* @return the merged object (target).
*/
public static JsonObject deepMerge(JsonObject source, JsonObject target) throws Exception {
for (Map.Entry<String,JsonElement> sourceEntry : source.entrySet()) {
String key = sourceEntry.getKey();
JsonElement value = sourceEntry.getValue();
if (!target.has(key)) {
//target does not have the same key, so perhaps it should be added to target
if (!value.isJsonNull()) //well, only add if the source value is not null
target.add(key, value);
} else {
if (!value.isJsonNull()) {
if (value.isJsonObject()) {
//source value is json object, start deep merge
deepMerge(value.getAsJsonObject(), target.get(key).getAsJsonObject());
} else {
target.add(key,value);
}
} else {
target.remove(key);
}
}
}
return target;
}
/**
* simple test
*/
public static void main(String[] args) throws Exception {
JsonParser parser = new JsonParser();
JsonObject a = null;
JsonObject b = null;
a = parser.parse("{offer: {issue1: null, issue2: null}, accept: true, reject: null}").getAsJsonObject();
b = parser.parse("{offer: {issue2: value2}, reject: false}").getAsJsonObject();
System.out.println(deepMerge(a,b));
// prints:
// {"offer":{},"accept":true}
a = parser.parse("{offer: {issue1: value1}, accept: true, reject: null}").getAsJsonObject();
b = parser.parse("{offer: {issue2: value2}, reject: false}").getAsJsonObject();
System.out.println(deepMerge(a,b));
// prints:
// {"offer":{"issue2":"value2","issue1":"value1"},"accept":true}
}