Parse Dynamic Json Objects in gson

Issue

I have json structure like this,how I parse the json with help of Gson.I need to store the key values in json object,I tried many example related to dynamic array but dynamic json array without square brace I cannot parse using Gson.Any Solutions or need to do Manual Json Parse?If any one feel duplicate comment the answer below.

{ "Result":[[
      "Title",
      {
        "0": 1323,
        "1": 3358,
        "2": 2123,
        "3": 8536,
        "4": 1399,
        "5": 9303,
        "7": 9732,
        "8": 3433,
        "9": 1383
      }
    ],[
      "Title",
      {
        "0": 1323,
        "1": 3358,
        "2": 2123,
        "3": 8536,
      }
    ]]}

Solution

To start, your JSON causes an exception to be thrown because it is invalid – You have an extra comma at the end of the last value in the second example. "3": 8536, should be "3": 8536.

After fixing that, this should be a simple task provided you define your objects correctly. Here is what I came up with:

public class Results {
    @SerializedName("Result")
    List<Result> results;
}

public class Result {
    String title;
    Map<String, Integer> results;
}

From there, the Result class needs to be deserialized in a special fashion, since the fields in the Result class do not directly map to entries in the JSON. Instead, we need to pull off the first and second elements of the JsonArray that is contained within each Result, and parse it accordingly. That looks like this:

public class ResultDeserializer implements JsonDeserializer<Result> {

    @Override
    public Result deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        JsonArray array  json.getAsJsonArray();

        Result result  new Result();
        result.title  array.get(0).getAsString();

        result.results  new LinkedHashMap<String, Integer>();
        for(Entry<String, JsonElement> entry : array.get(1).getAsJsonObject().entrySet()) {
            result.results.put(entry.getKey(), entry.getValue().getAsInt());
        }

        return result;
    }   
}

Note that my example omits error checking. Finally, register this deserializer, and you should be all set:

Gson gson  new GsonBuilder().registerTypeAdapter(Result.class, new ResultDeserializer()).create();

Results results  gson.fromJson(json, Results.class);

for(Result r : results.results) {
    System.out.println("Title  " + r.title);
    for(Entry<String, Integer> entry : r.results.entrySet()) {
        System.out.println("\t " + entry.getKey() + " -> " + entry.getValue());
    }
}

This prints:

Title  Title
     0 -> 1323
     1 -> 3358
     2 -> 2123
     3 -> 8536
     4 -> 1399
     5 -> 9303
     7 -> 9732
     8 -> 3433
     9 -> 1383
Title  Title
     0 -> 1323
     1 -> 3358
     2 -> 2123
     3 -> 8536

I’ll leave it to the OP to implement the reverse, that is a serializer for Result to produce the same results.

Answered By – nickb

Leave a Comment