通常,我需要合并两个JSON对象(类似于jQuery的$.extend()
工作方式).但是,Gson库没有内置功能,他们说他们不会实现它.
做类似的事情:
private void merge(JsonObject firstObj, JsonObject secondObj){ for(String keyInSecondObj : secondObj.entrySet().keySet()) { if(!firstObj.has(keyInSecondObj )){ firstObj.add(secondMap.get(keyInSecondObj)); } }
太简单了,因为它不处理递归合并JsonObjects,当两个映射中都存在键时不处理冲突,并且没有对非原始值(如Arrays)进行特殊处理.
我没有找到任何预先构建的解决方案来做到这一点.我更喜欢使用已经过彻底测试的东西,而不是编写我自己的方法,但它必须是Gson(不是Jackson或其他).
编辑:我最后编写了自己的实现,因为已经添加了作为这个问题的答案
这个问题是不是因为它不使用GSON(或Java为此事)中的重复.
这是我第一次尝试编写自己的静态合并方法.随意戳它的洞.
import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import java.util.Map; public class GsonTools { public static enum ConflictStrategy { THROW_EXCEPTION, PREFER_FIRST_OBJ, PREFER_SECOND_OBJ, PREFER_NON_NULL; } public static class JsonObjectExtensionConflictException extends Exception { public JsonObjectExtensionConflictException(String message) { super(message); } } public static void extendJsonObject(JsonObject destinationObject, ConflictStrategy conflictResolutionStrategy, JsonObject ... objs) throws JsonObjectExtensionConflictException { for (JsonObject obj : objs) { extendJsonObject(destinationObject, obj, conflictResolutionStrategy); } } private static void extendJsonObject(JsonObject leftObj, JsonObject rightObj, ConflictStrategy conflictStrategy) throws JsonObjectExtensionConflictException { for (Map.EntryrightEntry : rightObj.entrySet()) { String rightKey = rightEntry.getKey(); JsonElement rightVal = rightEntry.getValue(); if (leftObj.has(rightKey)) { //conflict JsonElement leftVal = leftObj.get(rightKey); if (leftVal.isJsonArray() && rightVal.isJsonArray()) { JsonArray leftArr = leftVal.getAsJsonArray(); JsonArray rightArr = rightVal.getAsJsonArray(); //concat the arrays -- there cannot be a conflict in an array, it's just a collection of stuff for (int i = 0; i < rightArr.size(); i++) { leftArr.add(rightArr.get(i)); } } else if (leftVal.isJsonObject() && rightVal.isJsonObject()) { //recursive merging extendJsonObject(leftVal.getAsJsonObject(), rightVal.getAsJsonObject(), conflictStrategy); } else {//not both arrays or objects, normal merge with conflict resolution handleMergeConflict(rightKey, leftObj, leftVal, rightVal, conflictStrategy); } } else {//no conflict, add to the object leftObj.add(rightKey, rightVal); } } } private static void handleMergeConflict(String key, JsonObject leftObj, JsonElement leftVal, JsonElement rightVal, ConflictStrategy conflictStrategy) throws JsonObjectExtensionConflictException { { switch (conflictStrategy) { case PREFER_FIRST_OBJ: break;//do nothing, the right val gets thrown out case PREFER_SECOND_OBJ: leftObj.add(key, rightVal);//right side auto-wins, replace left val with its val break; case PREFER_NON_NULL: //check if right side is not null, and left side is null, in which case we use the right val if (leftVal.isJsonNull() && !rightVal.isJsonNull()) { leftObj.add(key, rightVal); }//else do nothing since either the left value is non-null or the right value is null break; case THROW_EXCEPTION: throw new JsonObjectExtensionConflictException("Key " + key + " exists in both objects and the conflict resolution strategy is " + conflictStrategy); default: throw new UnsupportedOperationException("The conflict strategy " + conflictStrategy + " is unknown and cannot be processed"); } } } }