1

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?

ads
  • 1,703
  • 2
  • 18
  • 35
  • Maybe this can help https://stackoverflow.com/questions/53611583/handle-json-response-with-multiple-type-of-the-same-name/53613811#53613811 . Please add some code, at least your "object" class – Nicola Gallazzi Jan 08 '19 at 16:17

3 Answers3

2

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();
ads
  • 1,703
  • 2
  • 18
  • 35
0

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 

  }

}

JsonElement ref

Using Gson to get list of items or single model

vikas kumar
  • 10,447
  • 2
  • 46
  • 52
0

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.

pirho
  • 11,565
  • 12
  • 43
  • 70