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" } ] } }
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).
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.
Gson is first constructed using GsonBuilder and then, toJson(Object) or fromJson(String, Class) methods are used to read/write JSON constructs.
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.
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);
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 + '}'; } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With