De-serializing a nested, generic class with gson

Using Gson, I am trying to de-serialize a nested, generic class. The structure of the class is as follows:

The Wrapper object is simplified, but usually contains other properties, such as statusMessage , that are returned with the data field from the server:

 public class Response<T> { private List<T> data = null; public List<T> getData() { return this.data; } } 

A simple class, the expected output from the data field is higher (although as an array):

 public class Language { public String alias; public String label; } 

Using:

 Type type = new TypeToken<Response<Language>>() {}.getType(); Response<Language> response = new Gson().fromJson(json, type); List<Language> languages = response.getData(); Language l = languages.get(0); System.out.println(l.alias); // Error occurs here 

Where json -variable is something like this .

However, when doing this, I get the following exception (on line 3, the last code example):

ClassCastException: com.google.gson.internal.StringMap cannot be attributed to the book. Tongue

The exception ONLY occurs when saving data from getData() to a variable (or when used as one).

Any help would be greatly appreciated.

+4
source share
1 answer

The problem you are really facing is not directly related to Gson , but because of how arrays and generics play together.

You will find that in reality you cannot make new T[10] in a class like yours. see How to create a shared array in Java?

Basically you have two options:

  • Write your own deserializer and build the T[] array there, as shown in the SO question I linked above.
  • Use List<T> instead, then it will just work. If you really need to return an array, you can always just call List.toArray() in your method.

Edited from the comments below:

This is a fully working example:

 public class App { public static void main( String[] args ) { String json = "{\"data\": [{\"alias\": \"be\",\"label\": \"vitryska\"},{\"alias\": \"vi\",\"label\": \"vietnamesiska\"},{\"alias\": \"hu\",\"label\": \"ungerska\"},{\"alias\": \"uk\",\"label\": \"ukrainska\"}]}"; Type type = new TypeToken<Response<Language>>(){}.getType(); Response<Language> resp = new Gson().fromJson(json, type); Language l = resp.getData().get(0); System.out.println(l.alias); } } class Response<T> { private List<T> data = null; public List<T> getData() { return this.data; } } class Language { public String alias; public String label; } 

Output:

will be

+8
source

All Articles