Removing a deserialization of an arbitrary json object array in inner classes using Gson or a nested inner class

I am having problems when I try to deserialize a single Json line with Gson. The line looks something like this: (Note: I just simplified this, but leaving the part I came across and there might be Json syntax errors, but I checked with an online check that the line I'm working with is in order):

// let call this "container" json element { "context": "context", "cpuUsage": cpuUsageValue, "name": "thename", "rates": { "definition": [ { "key": "name", "type": "string" }, { "key": "rate", "type": "double" } ] "rows": [ { "name": "thename1", "rate": therate }, { "name": "thename2", "rate": therate2 } ] } 

Now the problem is that I am trying to deserialize json arrays ("definition" and "strings"). The remaining fields get the correct values ​​when deserializing. The definition of the class I'm using is as follows (there are no getters / setters for simplicity):

 public class Container { private String context; private Double cpuUsage; private String name; private RateContainer rates; public Container() { } } 

RateContainer (internal static class for the Container class, according to the Gson specifications):

 public static class RateContainer { private List<DefinitionContainer> definition; private List<RowsContainer> rows; public static class DefinitionContainer { String key; String type; public DefinitionContainer() { } } public static class RowsContainer { String name; Double rate; public RowsContainer() { } } public RateContainer() { } } 

To parse a Json string, I use:

 Container container = gson.fromJson(containerString, Container.class); 

and I get the following exception:

 Expecting object found: [{"key":"name","type":"string"},{"key":"rate","type":"double"}] 

There seems to be something in the class definition that doesn't work. I checked the Gson API, and I know that to deserialize lists usually do the following:

 Type collectionType = new TypeToken<Collection<Integer>>(){}.getType(); Collection<Integer> ints2 = gson.fromJson(json, collectionType); 

so I thought that maybe I could get these arrays first, using something like:

 JsonElement element = containerJsonElement.getAsJsonObject().get("rates"); 

and then get the "definition" and the "string", but I would prefer to save everything in the Container object. Is there a way to deserialize these lists this way? Is there something wrong with the class definition?

Thank you all in advance!

+1
source share
1 answer

In response to a few things in the original question, pay attention to the following three things:

  • Gson does not require deserialization for static inner classes.
  • You only need to use the TypeToken generator if the type of the deserialized type is a generic collection. If the type to be deserialized contains only such a collection, then using a generator TypeToken not required.
  • The main advantage of using an API such as Gson or Jackson is the simple mapping and serialization / deserialization of Java data structures to / from JSON. This way you can avoid using components like JsonElement .

In the example, JSON is fixed as

 { "context": "context", "cpuUsage": "cpuUsageValue", "name": "thename", "rates": { "definition": [ { "key": "name", "type": "string" }, { "key": "rate", "type": "double" } ], "rows": [ { "name": "thename1", "rate": "therate" }, { "name": "thename2", "rate": "therate2" } ] } } 

... then the following deserialize (and serialize) simply and as expected.

 import java.io.FileReader; import java.util.List; import com.google.gson.Gson; public class Foo { public static void main(String[] args) throws Exception { Gson gson = new Gson(); Container container = gson.fromJson(new FileReader("input.json"), Container.class); System.out.println(gson.toJson(container)); } } class Container { private String context; private String cpuUsage; private String name; private Rates rates; } class Rates { private List<Definition> definition; private List<Row> rows; } class Definition { private String key; private String type; } class Row { private String name; private String rate; } 
+6
source

All Articles