我经常需要合并两个 JSON 对象(类似于 jQuery 的 $.extend()
的工作方式)。但是,Gson 库没有内置功能,他们说 they won't implement it .
做类似的事情:
private void merge(JsonObject firstObj, JsonObject secondObj){
for(String keyInSecondObj : secondObj.entrySet().keySet()) {
if(!firstObj.has(keyInSecondObj )){
firstObj.add(secondMap.get(keyInSecondObj));
}
}
太简单了,因为它不处理递归合并 JsonObjects,不处理当键存在于两个映射中时的冲突,并且对非原始值(如数组)没有特殊处理。
我找不到任何预构建的解决方案来执行此操作。我更愿意使用经过彻底测试的东西,而不是编写我自己的方法,但它必须是 Gson(不是 Jackson 或其他)。
编辑:我最终编写了自己的实现,并添加为 answer to this question
This question 不是重复项,因为它没有使用 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.Entry<String, JsonElement> rightEntry : 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");
}
}
}
}
关于java - 在 Java 中使用 Gson 合并/扩展 JSON 对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34092373/