Reputation: 1723
I am calling a REST service (not mine) using retrofit which either returns a list of objects (if there are multiple) or a single object (if one). I was able to find a similar issue here however the suggestion is to change the API which i don't have control of. I also read this thread which seems to be a good approach but is there a way to handle this using Retrofit?
Upvotes: 1
Views: 2094
Reputation: 1723
While the answer from @pirho seems to be applicable, I found out a different and simple solution which worked for me. Hopefully it may help others as well.
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(baseUrl)
.addConverterFactory(JacksonConverterFactory.create(mapper))
.client(okHttpClient)
.build();
Upvotes: 2
Reputation: 12215
As the author of the 2nd post you referred I also refer to the implementation of PostArrayOrSingleDeserializer
described in that answer of mine.
When using Gson with Retrofit (Retrofit's converter-gson) you just need to register the adapter with custom Gson
instance and build the Retrofit
instance with that Gson
instance, see below example helper class:
public class MyRetrofit {
public static MyAPI getMyApi() {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Object.class,
new ObjectArrayOrSingleDeserializer())
.create();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://example.org")
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
return retrofit.create(MyAPI.class);
}
}
So the Object
in the JsonDeserializer
named ObjectArrayOrSingleDeserializer
is the DTO you need to check for single instance or array. Replace Object
with corresponding DTO and modify deserializer accordingly.
Upvotes: 0
Reputation: 11018
You can get the API response data as Map<String, JsonElement>
in response and then parse it based on your requirement directly. As you can check here if JsonElement is JsonArray
for ex:
public fun parseData(val jsonElement:JsonElement){
val gson = Gson()
if(jsonElementFromServer.isJsonArray()){
//here you can just parse it into some list of array
}else{
//here you can parse using gson to single item element or model
}
}
Using Gson to get list of items or single model
Upvotes: 0