将对象修改合并到java对象(JSON)

时间:2015-11-02 10:07:04

标签: java json gson

我想通过将json String传递给我的应用程序来修改java对象。字符串包含有关完整修改对象的所有信息,但仅包含要设置的单个成员。

class SomeClass {

    Object var1 = "Hello";
    Object var2 = "AAA";

    // A lot of fields goes here ...

}

public AppTest() throws Exception {

    SomeClass myObject = new SomeClass();
    myObject.var2 = "BBB";

    String modification = "{\"var1\":\"Goodbye\"}";

    Gson gson = new Gson();
    SomeClass modifed = gson.fromJson(modification, SomeClass.class);

    // TODO: Merge a modifed object into myObject somehow

}

此外,某些字段可能是具有任意数量字段的对象。同样,我可能只想修改子对象内的单个基元。一个更复杂的例子:

class SomeOtherClass {

    String var4 = "444";
    String var5 = "555";

}

class SomeClass {

    Object var1 = "111";
    Object var2 = "222";
    SomeOtherClass var3 = new SomeOtherClass();

}

public AppTest() throws Exception {

    SomeClass myObject = new SomeClass();
    myObject.var2 = "AAA";
    myObject.var3.var5 = "BBB";

    String modification = "{\"var3\":{\"var5\":\"XXX\"}}";

    Gson gson = new Gson();
    SomeClass modifed = gson.fromJson(modification, SomeClass.class);

    // TODO: Merge the modifed object into myObject somehow

}

所以,我的问题是如何用JSON部分修改对象?

3 个答案:

答案 0 :(得分:1)

您好我尝试了一个伪样本,如下所示:

static Object merge(Object target, Object modified) {

        for (Field f : target.getClass().getDeclaredFields()) {
            if (!f.isAccessible()) {
                f.setAccessible(true);
            }
            if (f.getType().isPrimitive()) {

                    try {
                        if (f.getType().isAssignableFrom(java.lang.Boolean.TYPE)
                                && f.getBoolean(modified) != f.getBoolean(target)) {
                            f.setBoolean(target, f.getBoolean(modified));
                        } else if (f.getType().isAssignableFrom(java.lang.Character.TYPE)
                                && f.getChar(modified) != f.getChar(target)) {
                            f.setChar(target, f.getChar(modified));
                        } else if (f.getType().isAssignableFrom(java.lang.Integer.TYPE)
                                && f.getInt(modified) != f.getInt(target)) {
                            f.setInt(target, f.getInt(modified));
                        }
                        //....
                        // do it for all other primitive types
                       //also consider Enum types(not primitive so check 'f.getType().isEnum()') 
                    } catch (IllegalArgumentException e) {
                        e.printStackTrace();
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }


            } else if (f.getType().getPackage().getName().matches("java.lang.*")
                    || f.getType().getPackage().getName().matches("java.util.*")) {
                /* Here I am trying to directly assign changes for the basic packages, if you want more you can add more packages*/

                try {
                    if (f.get(modified) != null && f.get(target) != f.get(modified)) {
                        f.set(target, f.get(modified));
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            } else {
                /* If local classes encountered as member variables then do the same merge!*/
                try {
                    merge(f.get(target), f.get(modified));
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
            }

        }
        return target;

    }

您可以将此方法称为myObject = (SomeClass) merge(myObject, modifed);

注意:这不是一个功能齐全的方法来完成你的工作,你请阅读内联评论,并使其成为一个完美的案例。我只确保基本功能

答案 1 :(得分:1)

管理以创建用于替换JsonObject中的属性的递归方法。

private static void mergeObjects(JsonObject object, JsonObject modification) {

    // Iterate through the modified properties
    for (Entry<String, JsonElement> entry : modification.entrySet()) {

        JsonElement je = entry.getValue();

        // If the modified property is an object, iterate through the properties of the modified property
        if (je instanceof JsonObject) {

            JsonObject nextOrigObject = object.get(entry.getKey()).getAsJsonObject();
            JsonObject nextModObject = je.getAsJsonObject();

            mergeObjects(nextOrigObject, nextModObject);

        }

        // If the modified property is not an object, set the original object to match the modified property
        else
            object.add(entry.getKey(), je);

    }

}

使用此方法,我可以合并两个对象,如下所示:

class SomeClass {

    Object var1 = "Hello";
    Object var2 = "AAA";

}

public TestApplication() {

    SomeClass myObject = new SomeClass();
    myObject.var2 = "BBB";

    String modificationString = "{\"var1\":\"Goodbye\"}";

    Gson gson = new Gson();
    JsonObject original = gson.fromJson(gson.toJson(myObject), JsonObject.class);
    JsonObject modification = gson.fromJson(modificationString, JsonObject.class);


    mergeObjects(original, modification);
    myObject = gson.fromJson(original, SomeClass.class);

    System.out.println(myObject.var1); // Prints "Goodbye"

}

public static void main(String[] args) {
    new DummyFile();
}

评论

在合并之前,可能有更漂亮的方法将SomeClass对象转换为JsonObject,随时添加您的建议。

编辑:在合并方法

中添加了其他内容

EDIT2:添加了评论

答案 2 :(得分:-1)

执行此操作时出现任何问题

    modifed.var2=myObject.var2;
    String modificationStr =  gson.toJson(modifed);
    System.out.println(modificationStr);