Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing nested JSON data using GSON

I'm trying to parse some JSON data using gson in Java that has the following structure but by looking at examples online, I cannot find anything that does the job.

Would anyone be able to assist?

{     "data":{         "id":[             {                 "stuff":{                  },                 "values":[                     [                         123,                         456                     ],                     [                         123,                         456                     ],                     [                         123,                         456                     ],                  ],                 "otherStuff":"blah"             }         ]     } } 
like image 688
user2844485 Avatar asked Oct 03 '13 21:10

user2844485


People also ask

Does Gson offer parse () function?

The GSON JsonParser class can parse a JSON string or stream into a tree structure of Java objects. GSON also has two other parsers. The Gson JSON parser which can parse JSON into Java objects, and the JsonReader which can parse a JSON string or stream into tokens (a pull parser).

How does Gson from JSON work?

By default, Gson tries to map all fields in the Java object to the JSON file it creates and vice versa. But Gson allows to exclude certain fields for serialization and deserialization. GSon can for example not serialize Java Beans, as the IPropertyChangeSupport field lead to an infinite loop.

Which Gson methods are useful for implementing JSON?

Gson is first constructed using GsonBuilder and then, toJson(Object) or fromJson(String, Class) methods are used to read/write JSON constructs.

What is the difference between Gson and Jackson?

Conclusion Both Gson and Jackson are good options for serializing/deserializing JSON data, simple to use and well documented. Advantages of Gson: Simplicity of toJson/fromJson in the simple cases. For deserialization, do not need access to the Java entities.


2 Answers

You just need to create a Java class structure that represents the data in your JSON. In order to do that, I suggest you to copy your JSON into this online JSON Viewer and you'll see the structure of your JSON much clearer...

Basically you need these classes (pseudo-code):

class Response   Data data  class Data   List<ID> id  class ID   Stuff stuff   List<List<Integer>> values   String otherStuff 

Note that attribute names in your classes must match the names of your JSON fields! You may add more attributes and classes according to your actual JSON structure... Also note that you need getters and setters for all your attributes!

Finally, you just need to parse the JSON into your Java class structure with:

Gson gson = new Gson(); Response response = gson.fromJson(yourJsonString, Response.class); 

And that's it! Now you can access all your data within the response object using the getters and setters...

For example, in order to access the first value 456, you'll need to do:

int value = response.getData().getId().get(0).getValues().get(0).get(1); 
like image 87
MikO Avatar answered Sep 21 '22 23:09

MikO


Depending on what you are trying to do. You could just setup a POJO heirarchy that matches your json as seen here (Preferred method). Or, you could provide a custom deserializer. I only dealt with the id data as I assumed it was the tricky implementation in question. Just step through the json using the gson types, and build up the data you are trying to represent. The Data and Id classes are just pojos composed of and reflecting the properties in the original json string.

public class MyDeserializer implements JsonDeserializer<Data> {    @Override   public Data deserialize(JsonElement je, Type type, JsonDeserializationContext jdc) throws JsonParseException   {     final Gson gson = new Gson();     final JsonObject obj = je.getAsJsonObject(); //our original full json string     final JsonElement dataElement = obj.get("data");     final JsonElement idElement = dataElement.getAsJsonObject().get("id");     final JsonArray idArray = idElement.getAsJsonArray();      final List<Id> parsedData = new ArrayList<>();     for (Object object : idArray)     {       final JsonObject jsonObject = (JsonObject) object;       //can pass this into constructor of Id or through a setter       final JsonObject stuff = jsonObject.get("stuff").getAsJsonObject();       final JsonArray valuesArray = jsonObject.getAsJsonArray("values");       final Id id = new Id();       for (Object value : valuesArray)       {         final JsonArray nestedArray = (JsonArray)value;         final Integer[] nest =  gson.fromJson(nestedArray, Integer[].class);         id.addNestedValues(nest);       }       parsedData.add(id);    }    return new Data(parsedData);   } 

}

Test:

  @Test   public void testMethod1()   {     final String values = "[[123, 456], [987, 654]]";     final String id = "[ {stuff: { }, values: " + values + ", otherstuff: 'stuff2' }]";     final String jsonString = "{data: {id:" + id + "}}";     System.out.println(jsonString);     final Gson gson = new GsonBuilder().registerTypeAdapter(Data.class, new MyDeserializer()).create();     System.out.println(gson.fromJson(jsonString, Data.class));   } 

Result:

Data{ids=[Id {nestedList=[[123, 456], [987, 654]]}]} 

POJO:

public class Data {    private List<Id> ids;    public Data(List<Id> ids)   {    this.ids = ids;   }    @Override   public String toString()   {     return "Data{" + "ids=" + ids + '}';   }  }    public class Id  {     private List<Integer[]> nestedList;     public Id()    {     nestedList = new ArrayList<>();    }     public void addNestedValues(final Integer[] values)    {     nestedList.add(values);    }     @Override    public String toString()    {     final List<String> formattedOutput = new ArrayList();     for (Integer[] integers : nestedList)     {      formattedOutput.add(Arrays.asList(integers).toString());     }     return "Id {" + "nestedList=" + formattedOutput + '}';   } } 
like image 26
Origineil Avatar answered Sep 19 '22 23:09

Origineil