3

I have some difficulties with json deserialization using GSon and I hope somebody can help me.

I want to deserialize the following json snippet:

{
    "fieldA": "valueA",
    "myCollection": {
        "AnotherClass": [
            {
                "objectAfieldA": "valueB",
                "objectAfieldB": "valueC"
            },
            {
                "objectAfieldA": "valueD",
                "objectAfieldB": "valueE"
            }
        ]
    }
}

the corresponding overall class has following fields:

...
String fieldA;
List<AnotherClass> = new ArrayList<AnotherClass>();
....

Now, my problem is that when I deserialize, using fromJson(jsonSample, resultContainer.class), without the List<T> element, everything is good, but I get a NullPointerException when I include the contained list. I've read about how to deal with collections of generic types and the use of TypeToken, but I can't apply this knowledge when my collection is part of another class…

I really would appreciate any help to solve this.

Programmer Bruce
  • 64,977
  • 7
  • 99
  • 97
  • If you took your code example from your work, then it won't compile as the List field has no name. If that isn't the problem, then take a look at [http://stackoverflow.com/questions/5554217/google-gson-deserialize-listclass-object-generic-type](http://stackoverflow.com/questions/5554217/google-gson-deserialize-listclass-object-generic-type), and [http://stackoverflow.com/questions/2496494/library-to-encode-decode-from-json-to-java-util-map](http://stackoverflow.com/questions/2496494/library-to-encode-decode-from-json-to-java-util-map). – oberger Jun 19 '11 at 16:37
  • You're right, I missed a name field. And the problem is solved in the subsequent answer. – Per Erik Gransøe Jun 19 '11 at 21:00

2 Answers2

4

The solution for deserealizing the unnamed JSON array is quite simple:

List<resultContainer> lres = gson.fromJson(new FileReader("input.json"), new TypeToken<List<resultContainer>>(){}.getType());
Andrew
  • 41
  • 2
2

When deserializing, you only need to use the TypeToken if the outer-most structure to be deserialized into is a generic collection. This is not the case for the example in the original question. So, use of a TypeToken is unnecessary.

The issue appears to be that the JSON structure does not match the Java structure attempting to be bound to.

The JSON structure defines

an object with two elements
    element 1 is a string named "fieldA",
    element 2 is an object named "myCollection", which has one element
        the one element is an array named "AnotherClass", composed of objects with two elements
            element 1 is a string named "objectAfieldA",
            element 2 is a string named "objectAfieldB"

So, define a Java data structure to match that, and deserialization will work very simply, without any custom processing necessary. If such a matching Java structure is not provided, then custom deserialization is necessary.

Here is such a working example using the names and types from the original question.

import java.io.FileReader;

import com.google.gson.Gson;

public class Foo
{
  public static void main(String[] args) throws Exception
  {
    Gson gson = new Gson();
    resultContainer result = gson.fromJson(new FileReader("input.json"), resultContainer.class);
    System.out.println(gson.toJson(result));
  }
}

class resultContainer
{
  String fieldA;
  MyCollectionContainer myCollection;
}

class MyCollectionContainer
{
  SomeOtherClass[] AnotherClass;
}

class SomeOtherClass
{
  String objectAfieldA;
  String objectAfieldB;
}
Programmer Bruce
  • 64,977
  • 7
  • 99
  • 97
  • Great answer, spot on! I ajusted my java structure and I'm happy again. Thanx, Bruce. – Per Erik Gransøe Jun 19 '11 at 21:02
  • Another issue came up now... The service I use may sometimes only carry one item inside the `AnotherClass` element in which case it is not encoded as a json array (casting perfectly to SomeOtherClass[]), but just a plain SomeOtherClass type - leaving the array brackets. That breaks my deserialization. If I add the brackets manually, it parses again. Is this JSON standard, and do you guys have a workaround? – Per Erik Gransøe Jun 20 '11 at 21:00
  • What you've described is an all-too-often occurring problem. Maybe some folks think that if the JSON they generate is valid, that's good enough, even if it is not consistently structured. Gson unfortunately does not yet have a simple configuration available to handle this often-occurring problem. Custom deserialization processing is necessary. I posted such an example in response to the question at http://stackoverflow.com/questions/6223023. – Programmer Bruce Jun 20 '11 at 22:09