Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将对象修改合并到java对象(JSON)_Java_Json_Gson - Fatal编程技术网

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

将对象修改合并到java对象(JSON),java,json,gson,Java,Json,Gson,我想通过向我的应用程序传递json字符串来修改java对象。字符串将不包含关于完整的、修改过的对象的所有信息,而只包含一个要设置的成员 class SomeClass { Object var1 = "Hello"; Object var2 = "AAA"; // A lot of fields goes here ... } public AppTest() throws Exception { SomeClass myObject = new Som

我想通过向我的应用程序传递json字符串来修改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部分修改对象?

这样做有问题吗

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

嗨,我试用了一个伪样本,如下所示:

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,modified)


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

能够创建一个递归方法来替换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);

    }

}
评论

在合并之前,可能有更好的方法将SomeClass对象转换为JsonObject,请随意添加您的建议

编辑:在合并方法中添加了else


EDIT2:添加注释

您是否建议我对对象的每个变量都这样做?在示例案例(后一个)中的“myObject”有4个json原语,我的应用程序可能有数百个。。。我该如何确定“修改过的”对象应该修改哪个变量?我的意思是:*我的类中的每个变量都非常感谢我的努力,我设法创建了一个方法来合并JSONObject。它在起作用,所以我想我会用它来代替。好吧,正如你所说,可能还有其他好方法。如果你的实现有效,你可以分享它。这对其他人会有帮助。如果你认为我应该使用你的方法,请告诉我。我写的代码没有考虑JSON-它可以用于任何java对象(但有点复杂)。您的代码看起来更干净、更简单,如果它满足需要,那么请坚持您的方法。我喜欢使用
JsonObject
作为基础的另一种方法。
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();
}