在 Java 中使用 Gson 合并/扩展 JSON 对象 [英] Merge/Extend JSON Objects using Gson in Java

查看:69
本文介绍了在 Java 中使用 Gson 合并/扩展 JSON 对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常,我需要合并两个 JSON 对象(类似于 jQuery 的 $.extend() 有效).但是,Gson 库没有内置功能,他们表示他们不会实施它.

Oftentimes, I have a need to merge two JSON Objects (similar to the way jQuery's $.extend() works). However, the Gson library has no built in functionality and they have said 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,不处理两个映射中都存在键时的冲突,并且对非原始值(如数组)没有特殊处理.

Is too simple because it doesn't handle recursively merging JsonObjects, doesn't handle conflicts when the key exists in both maps, and has no special handling for non-primitive values such as Arrays.

我没有找到任何预先构建的解决方案来做到这一点.我更愿意使用经过彻底测试的东西,而不是编写我自己的方法,但它必须是 Gson(不是 Jackson 或其他).

I failed to find any pre-built solutions to do this. I would prefer to use something that has been thoroughly tested instead of writing my own method, but it must be Gson (not Jackson or other).

我最终编写了自己的实现,并作为此问题的答案em>

这个问题不是重复因为它没有使用 Gson(或 Java).

This question is not a duplicate because it's not using Gson (or Java for that matter).

推荐答案

这是我第一次尝试编写自己的静态合并方法.随意在里面戳洞.

Here's my first attempt at writing my own static merge method. Feel free to poke holes in it.

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 中使用 Gson 合并/扩展 JSON 对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆