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?

1

3 Answers 3

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();
Sign up to request clarification or add additional context in comments.

Comments

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

Comments

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.

1 Comment

Thanks. Would happen to have a code snippet for Jackson instead of Gson?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.