将json解析为必要的对象

时间:2014-10-23 13:32:15

标签: java android json

在我的Android应用中,我有json,如下所示:

{
    "Records": [
        {
            "RowIndex": "0",
            "NameValue": {
                "Name": "PropertyName1",
                "Value": "PropertyValue1"
            }
        }{
            "RowIndex": "1",
            "NameValue": {
                "Name": "PropertyName2",
                "Value": "PropertyValue2"
            }
        }
    ]
}

我需要把这个json分成对象,看起来像:

public class MyClass {
    public String PropertyName1;
    public String PropertyName2;
}

解析后的结果应为:

public String PropertyName1 = "PropertyValue1";
public String PropertyName2 = "PropertyValue2";

基本上,第一个json相当于:

{
    "PropertyName1" : "PropertyValue1",
    "PropertyName2" : "PropertyValue2"
}

问题:如何在没有使用swith/case的情况下首先使用json来搜索必要的属性?

2 个答案:

答案 0 :(得分:2)

你必须走在我害怕的黑暗反思道路上。 你可以将json解析成一个中间对象,它有一个namevalue的映射。

然后你使用下面的代码(当然只是复制粘贴你需要的位)来遍历键/值对的映射。为每个键查找所需的字段并进行设置。如果您确保只需要设置公共变量,那么您可以使用getFields并跳过setAccessible。

public class Test {
    public static void main(String[] argv) {
        MyClass myClass = new MyClass();
        Class<?> classObject = myClass.getClass();

//        Field fields[] = classObject.getFields(); // if you want to get only public fields.
        Field fields[] = classObject.getDeclaredFields(); // any field
        for(Field f : fields) {
            System.out.println(f.getName());
            try {
                // if member is private: security managers may object but the default java allows it
                f.setAccessible(true);
                f.set(myClass, "abc");
            } catch (IllegalAccessException e) {
                // handle access exception:
                e.printStackTrace();
            }
        }

        System.out.println("prop 1: " + myClass.PropertyName1);
        System.out.println("prop 2: " + myClass.PropertyName2);
    }


    public static class MyClass {
        public String PropertyName1;
        private String PropertyName2;
    }
}

实际上......有一种非反射方式,但会取代你对象的实现。

如果你改变班级:

public class MyClass {
    public String PropertyName1;
    public String PropertyName2;
}

public class MyClass {
    private Map<String, String> properties = new HashMap<String, String>();
    public void setProperties(Map<String, String> props) { this.properties = props; }
    public String getPropertyName1() {
        return lookupProperty("PropertyName1");
    }
    public String getPropertyName2() {
        return lookupProperty("PropertyName2");
    }
    private String lookupProperty(String property) {
        if (properties.containsKey(property) {
            return properties.get(property);
        } else { 
            return null;
        }
    }
}

然后您可以将名称值映射解析为映射,并使用它构造myclass。 只是为了完整性而列出它,虽然改变域模型以适应json输入并不理想。

我建议使用这两种方法进行输入解析,然后将模型复制到实际的域对象中,而不是在应用程序中使用json-model。这样,如果json模型发生变化,你的域模型就不会改变。

答案 1 :(得分:1)

我能想到的一个方法(听起来不太好)是实际制作一个与你得到的JSON响应相匹配的对象。然后,将NameValue对象映射到MyClass

所以,像

public class NameValue {
   public string Name;
   public String Value;

   public MyClass getMyClass(){
         MyClass myClass = new MyClass();
         myClass.PropertyName2 = Value;
         return myClass;
   }
}

显然,你可以想出一个更好的方法来映射它。但这只是我可能会做的事情的一个例子,如果我得到了一个我并不特别关心的回复JSON。您可以类似地反转它(让MyClass能够创建NameValue对象),这样您就可以以正确的格式发回数据。