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

查看:586
本文介绍了使用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.

我找不到任何pre - 建立解决方案来做到这一点。我更喜欢使用经过彻底测试而不是编写自己的方法的东西,但它必须是 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).

编辑:我最终编写了自己的实现,因为已添加为回答此问题

这个问题 重复,因为它没有使用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天全站免登陆