1

Good morning,

I am struggling to use GSON to parse some JSON output from a particular web service. Here is some sample output:

[
    {
        "count": 1,
        "headings": [
            "name",
            "hosts",
            "Model",
        ],
        "kind": "Cluster",
        "offset": 0,
        "results": [
            [
                "cluster1",
                [
                   "host1",
                   "host2"
                ],
                [
                   "Virtual Machine",
                   "Virtual Machine"
                ]
            ]
        ]
    }
]

The "results" portion is the part I am having trouble processing. Basically since the results have mixed types, Lists and strings, I can't write an object that represents it. I've been reading that this may require a deserializer. I am slightly out of my depth on this and would appreciate any insight into how to solve this.

My classes that I am currently using looks like this:

public class ModelDefinition
{
    public Integer count ;
    public ArrayList<String> headings ;
    public String kind ;
    public Integer next_offset ;
    public Integer offset ;
    public String results_id ;
    public String next ;
}

public class LongModelDefinition extends ModelDefinition
{
    public ArrayList<String[][]> results ;
}

I understand why it isn't working, but I'm not sure how to fix it.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Possible duplicate of [Using GSON to parse array with multiple types](https://stackoverflow.com/questions/5377827/using-gson-to-parse-array-with-multiple-types) – user2340612 Aug 22 '18 at 14:10
  • 1
    I am not sure if gson is the best tool for this kind of json, perhaps handling the json with less abstraction like using Jackson may be a better option. In the example is not clear, but it could happen that if there were only one host instead of two, you receive a string instead of an array, increasing the complexity of the deserialization. – Juan Aug 22 '18 at 14:19
  • Actually you are correct. This web service will turn any single element list into a string, most annoying. I have no control over the web service, I'm just a client. I've handled this issue by being careful with my queries so far. However, it is making the code bloated and ugly and I'm looking for a cleaner way to deal with this. – ricknchicago Aug 22 '18 at 18:24

1 Answers1

0

You will not be able to use GSON or another JSON bindings for this ... without resorting to custom serializers / deserializers. The problem is that this:

   [
        [
            "cluster1",
            [
               "host1",
               "host2"
            ],
            [
               "Virtual Machine",
               "Virtual Machine"
            ]
        ]
   ]

cannot be represented by a statically typed Java data structure. At the 2nd level, you would need a list or array type whose elements are either strings or sublists / subarrays. Java doesn't support this. You could use Object[] or List<Object> and type casting, but bindings are not designed to coe with that kind of thing.

I see three alternatives:

1) You could alter the schema for this data; e.g.

   [
        [
            [
               "cluster1"
            ],
            [
               "host1",
               "host2"
            ],
            [
               "Virtual Machine",
               "Virtual Machine"
            ]
        ]
   ]

2) You could use a JSON parser that produces JSONObject / JSONArray objects, and deal with the non-uniformity yourself. (How you deal with it would be up to you. It will depend on what the "results" section actually means, and what you need to do with it.)

3) You could implement a GSON-based binding using custom (i.e. hand written) serializers / deserializers.

Stephen C
  • 698,415
  • 94
  • 811
  • 1,216
  • Yeah, sorry about that, there should not be colons after those three attributes. They are part of a list of strings. – ricknchicago Aug 23 '18 at 16:18