使用Gson库动态解析未知数据

时间:2017-03-30 07:36:42

标签: json generics gson

我想使用Gson库解析Android Studio中的JSON数据。但数据是通用的......不知道数据中有哪些键(对象)..

  

在学校对象下 - 数字1103是对象。

     

在那个对象下我们有shoolname,shortname,students   再次在学生之下 - 有像2201,2202这样的身份证......   这些物体是动态的,不知道是什么反应..

     

所以问题是如何使用Gson在android中解析这个json字符串?

     欢迎

或任何其他解决方案

{
"schools": {
    "home": "1103",
    "statelevel": "1348"
},
"school": {
    "1103": {
        "schoolname": "Indira School",
        "nameshort": "ind",
        "students": {
            "2201": {
                "name": "Ritesh",
                "isCR": true,
                "maths": {
                    "score": 95,
                    "lastscore": 86
                }
            },
            "2202": {
                "name": "Sanket",
                "maths": {
                    "score": 98,
                    "lastscore": 90
                }
            },
            "2203": {
                "name": "Ajit",
                "maths": {
                    "score": 94,
                    "lastscore": 87
                }
            }
        }
    },
    "1348": {
        "schoolname": "Patil School",
        "nameshort": "pat",
        "students": {
            "3201": {
                "name": "Ravi",
                "maths": {
                    "score": 95,
                    "lastscore": 86
                }
            },
            "3202": {
                "name": "Raj",
                "isCR": true,
                "maths": {
                    "score": 98,
                    "lastscore": 90
                }
            },
            "3203": {
                "name": "Ram",
                "maths": {
                    "score": 94,
                    "lastscore": 87
                }
            }
        }
    }
}

}

我已提到How to parse dynamic JSON fields with GSON? ..但在我的情况下没有用..我也有内部泛型类。

  1. 我在https://stackoverflow.com/a/23473650/7790252找到了解决方案。 实现反序列化器来模拟学校和学生等课程。

3 个答案:

答案 0 :(得分:2)

您可以简单地使用java.util.Map,它是一个关联键/值容器,其中键和值是任意对象,并且可以使用Gson直接与JSON动态对象对齐。您只需定义适当的映射(我将字段折叠以节省一些可视空间):

final class Response {
    @SerializedName("schools") final HomeSchool school = null;
    @SerializedName("school") final Map<Integer, School> schools = null;
}

final class HomeSchool {
    @SerializedName("home") final int home = Integer.valueOf(0);
    @SerializedName("statelevel") final int stateLevel = Integer.valueOf(0);
}

final class School {
    @SerializedName("schoolname") final String name = null;
    @SerializedName("nameshort") final String shortName = null;
    @SerializedName("students") final Map<Integer, Student> students = null;
}

final class Student {
    @SerializedName("name") final String name = null;
    @SerializedName("isCR") final boolean isCr = Boolean.valueOf(false);
    @SerializedName("maths") final Maths maths = null;
}

final class Maths {
    @SerializedName("score") final int score = Integer.valueOf(0);
    @SerializedName("lastscore") final int lastScore = Integer.valueOf(0);
}

现在,一旦你有了映射,就可以轻松地反序列化你的JSON:

private static final Gson gson = new Gson();

public static void main(final String... args) {
    final Response response = gson.fromJson(JSON, Response.class);
    for ( final Entry<Integer, School> schoolEntry : response.schools.entrySet() ) {
        final School school = schoolEntry.getValue();
        System.out.println(schoolEntry.getKey() + " " + school.name);
        for ( final Entry<Integer, Student> studentEntry : school.students.entrySet() ) {
            final Student student = studentEntry.getValue();
            System.out.println("\t" + studentEntry.getKey()
                    + " " + student.name
                    + " CR:" + (student.isCr ? "+" : "-")
                    + " (" + student.maths.score + ", " + student.maths.lastScore + ")"
            );
        }
    }
}
  

1103 Indira School
    2201 Ritesh CR:+(95,86)
    2202 Sanket CR: - (98,90)
    2203 Ajit CR: - (94,87)
  1348 Patil学校
    3201 Ravi CR: - (95,86)
    3202 Raj CR:+(98,90)
    3203 Ram CR: - (94,87)

类型标记建议部分正确:它们用于反序列化您不能或不具有具体映射的对象,例如某些内容的列表或字符串映射到某些内容。在你的情况下,Gson只需分析字段声明来解析地图类型(键和值)。

答案 1 :(得分:0)

来自Gson Documentation

 Type mapType = new TypeToken<Map<Integer, Result> >() {}.getType(); // define generic type
Map<Integer, Result> result= gson.fromJson(new InputStreamReader(source), mapType);

答案 2 :(得分:0)

创建实现JsonDeserializer

的模型对象

然后你有这个方法来覆盖:

@Override
public ActivityEvents deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
    JsonObject jObject = jsonElement.getAsJsonObject();
    for (Map.Entry<String, JsonElement> entry : jObject.entrySet()) {
    entry.getKey(); //here you can get your key 
    gson.fromJson(entry.getValue(), StudebtInfo.class);; //here you can get value for key
    }
}