Reputation: 7
I'm working on API Requests with Retrofit(1.9.0) and gson library (1.7.0 I have compatibility issues with version 2.3.1 of gson) on Android, I make some request to an API which have same format of response but different content following the url call, but I encounter a problem for a deserialization of one answer which there is array inside. This is an example of the json I want to deserialize :
{
"http_code":200,
"content":[
{
"name":"Groult Christian",
"location":[
48.897655,
2.252462
],
"website":null,
"address":{
"street_address":"XXXXXX",
"city":"XXXXXX",
"state":null,
"postal_code":"XXXXXX",
"country":"XXXXXX"
},
"global_score":0,
"popularity_score":0,
"quality_score":0,
"createdAt":"2015-02-18T02:13:05.068Z",
"updatedAt":"2015-02-18T02:13:05.068Z",
"id":"54e3f531775288ca572872ac"
},
...
]
}
My DeserializerJson and how I call it for retrofit:
public class DeserializerJson<T> implements JsonDeserializer<T> {
@Override
public T deserialize(JsonElement je, Type type, JsonDeserializationContext jdc)
throws JsonParseException
{
// Get the "content" element from the parsed JSON
JsonElement content = je.getAsJsonObject().get("content");
// Deserialize it. You use a new instance of Gson to avoid infinite recursion
// to this deserializer
return new Gson().fromJson(content, type);
}
}
...
Gson gson = new GsonBuilder()
.registerTypeAdapter(ContentUser.class, new DeserializerJson<ContentUser>())
.registerTypeAdapter(DeviceInfo.class, new DeserializerJson<DeviceInfo>())
.registerTypeAdapter(PlacesModel.class, new DeserializerJson<PlacesModel>())
.create();
RestAdapter restAdapter = new RestAdapter.Builder()
.setLogLevel(RestAdapter.LogLevel.BASIC)
.setConverter(new GsonConverter(gson))
...
...
and my different models:
public class PlacesModel {
@SerializedName("name")
@Expose
private String name;
@SerializedName("location")
@Expose
private List<Double> location = new ArrayList<Double>();
@SerializedName("website")
@Expose
private Object website;
@SerializedName("address")
@Expose
private AddressModel address;
@SerializedName("global_score")
@Expose
private Integer globalScore;
@SerializedName("popularity_score")
@Expose
private Integer popularityScore;
@SerializedName("quality_score")
@Expose
private Integer qualityScore;
@SerializedName("createdAt")
@Expose
private String createdAt;
@SerializedName("updatedAt")
@Expose
private String updatedAt;
@Expose
@SerializedName("id")
private String id;
/* Getters and Setters... */
}
public class AddressModel {
@SerializedName("street_address")
@Expose
private String streetAddress;
@SerializedName("city")
@Expose
private String city;
@SerializedName("state")
@Expose
private Object state;
@SerializedName("postal_code")
private String postalCode;
@SerializedName("country")
@Expose
private String country;
/* Getters and Setters... */
}
url call in Api Manager is like this:
@GET("/places")
public void getPlaces(RestCallback<List<PlacesModel>> callback);
But when I do the call I get this error : com.google.gson.JsonParseException: The JsonDeserializer com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter@3b8aa06 failed to deserialize json object
Everything is fine for other call I get all content and so with no problem but one where there is array inside content I got an error and I don't understand why I believed if I just put a list of my model it will be fine but it doesn't work. I think I miss something so if someone can help me
Thanks in advance
Upvotes: 0
Views: 3313
Reputation: 12365
The problem of your issue is that you register DeserializerJson
for PlacesModel
class and in getPlaces method your response is List<PlacesModel>
class. List<PlacesModel>
is a different class as PlacesModel
so Gson doesn't know how to deserialise List<PlacesModel>
. What you have to do is register one more Deserialiser by this method:
.registerTypeAdapter(List.class, new DeserializerJson<List<PlacesModel>>())
If you use more than one type of List
(I mean List<PlacesModel>
and List< DeviceInfo >
) You can define your own TypeAdapter
or you cN change list to array and register deserialiser for them as is shown below
.registerTypeAdapter(PlacesModel[].class, new DeserializerJson<PlacesModel[]>())
Now everything works fine for yours json.
Upvotes: 1