Using the Gson library to dynamically analyze unknown data

I want to parse the following JSON data in Android Studio using the Gson library. But the data is generalized. I don't know what keys (objects) get into the data.

under the school object - there is number 1103, which is the object.

and under this object we have shoolname, shortname, students again under students - there are IDs 2201, 2202 ... these objects are dynamic, I don't know what comes back.

So the question is how to parse this json string in android using Gson?

or any other solution for this is welcome

{
"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
                }
            }
        }
    }
}

      

}

I referenced How to parse dynamic JSON fields with GSON? .. but didn't work in my case .. I also have internal shared classes.

  • I found a solution here on StackOverflow question . implements a deserializer for modeling classes like school and students.
+3


source to share


3 answers


You can just use java.util.Map

which is a key / value associative container where keys and values ​​are arbitrary objects and can be consistent with dynamic JSON objects using Gson in a very straight forward manner. You just need to define the appropriate mappings (I made the field collapsed to save some visible space):

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);
}

      

Now that you have the mappings, you can deserialize your JSON easily:



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 School
  3201 Ravi CR: - (95, 86)
  3202 Raj CR: + (98, 90)
  3203 Ram CR: - (94, 87)

The type marker suggestions are partially correct: they are used to deserialize objects that you cannot or do not have specific mappings, such as lists of something or string maps. In your case, Gson just parses field declarations to resolve map types (both keys and values).

+2


source


From Gson Documentation



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

      

0


source


Create a model object that implements JsonDeserializer

then you have this method to override:

@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
    }
}

      

0


source







All Articles