I have some problems with implementation of Json Deserialization in my Android application (with Gson library)
I've made class like this
public class MyJson<T>{ public List<T> posts; }
And Deserialization call is:
public class JsonDownloader<T> extends AsyncTask<Void, Void, MyJson<T>> { ... protected MyJson<T> doInBackground(Void... params) { ... Reader reader = new InputStreamReader(content); GsonBuilder gson = new GsonBuilder(); Type collectionType = new TypeToken<MyJson<T>>() {}.getType(); result = gson.create().fromJson(reader, collectionType); ... } }
Problem is that result.posts list after call holds one Array of LinkedTreeMap Objects(with correct values so problem is Deserialization) instead of MyJson Objects. When I use MyObject instead of T everything is running fine and MyObject is correct.
So is there any way to implement deserialization call without creating custom deserializer?
Deserialization – Read JSON using Gson. Deserialization in the context of Gson means converting a JSON string to an equivalent Java object. In order to do the deserialization, we need a Gson object and call the function fromJson() and pass two parameters i.e. JSON string and expected java type after parsing is finished ...
3. Deserialize JSON With Extra Unknown Fields to Object. As you can see, Gson will ignore the unknown fields and simply match the fields that it's able to.
Gson will not work on objects with recursive references. Gson requires the class to have a default no-args constructor. If the no-args constructor is not provided, we can register an InstanceCreator with Gson, allowing us to deserialize instances of classes.
protected TypeToken() Constructs a new type literal. Derives represented class from type parameter. Clients create an empty anonymous subclass.
You have to specify the type of T
at the time of deserialization. How would your List
of posts
get created if Gson
didn't know what Type
to instantiate? It can't stay T
forever. So, you would provide the type T
as a Class
parameter.
Now assuming, the type of posts
was String
you would deserialize MyJson<String>
as (I've also added a String json
parameter for simplicity; you would read from your reader
as before):
doInBackground(String.class, "{posts: [\"article 1\", \"article 2\"]}"); protected MyJson<T> doInBackground(Class<T> type, String json, Void... params) { GsonBuilder gson = new GsonBuilder(); Type collectionType = new TypeToken<MyJson<T>>(){}.getType(); MyJson<T> myJson = gson.create().fromJson(json, collectionType); System.out.println(myJson.getPosts()); // ["article 1", "article 2"] return myJson; }
Similarly, to deserialize a MyJson
of Boolean
objects
doInBackground(Boolean.class, "{posts: [true, false]}"); protected MyJson<T> doInBackground(Class<T> type, String json, Void... params) { GsonBuilder gson = new GsonBuilder(); Type collectionType = new TypeToken<MyJson<T>>(){}.getType(); MyJson<T> myJson = gson.create().fromJson(json, collectionType); System.out.println(myJson.getPosts()); // [true, false] return myJson; }
I've assumed MyJson<T>
for my examples to be as
public class MyJson<T> { public List<T> posts; public List<T> getPosts() { return posts; } }
So, if you were looking for to deserialize a List<MyObject>
you would invoke the method as
// assuming no Void parameters were required MyJson<MyObject> myJson = doInBackground(MyObject.class);
Have you tried?
gson.create().fromJson(reader, MyJson.class);
EDIT
After reading this post it seems that you use of Type
is correct. I believe your issue is the use of T
. You must remember that with Java there is type-erasure. This means that at runtime all instances of T
are replaced with Object
. Therefore at runtime what you are passing GSON is really MyJson<Object>
. If you tried this with a concrete class in place of <T>
I believe it would work.
Google Gson - deserialize list<class> object? (generic type)
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