François Legrand
François Legrand

Reputation: 1233

Add an array as request parameter with Retrofit 2

I'm looking for way to add an int array (e.g [0,1,3,5]) as parameter in a GET request with retrofit 2. Then, the generated url should be like this : http://server/service?array=[0,1,3,5]

How to do this ?

Upvotes: 28

Views: 37848

Answers (8)

ananth
ananth

Reputation: 11

You can pass the value as below

In Repository

getApiResponse(arrayOf(0,1,3,5).contentToString())` In Kotlin.

@GET("http://server/service")
suspend fun getApiResponse(@Query("array") array: String): Response

It will work.

Upvotes: 0

jqgsninimo
jqgsninimo

Reputation: 7038

Use Iterable to encapsulate the integer list, or use a two-dimensional integer array.

  • How to define:

    public interface ServerService {
        @GET("service")
        Call<Result> method1(@Query("array") Iterable<List<Integer>> array);
    
        @GET("service")
        Call<Result> method2(@Query("array") Integer[][] array);
    }
    
  • How to use:

    Retrofit retrofit = new Retrofit.Builder()
        .baseUrl("http://server/")
        .addConverterFactory(GsonConverterFactory.create())
        .build();
    ServerService service = retrofit.create(ServerService.class);
    
    // Use the first method.
    List<Integer> data1 = Arrays.asList(0,1,3,5);
    Iterable array1 = Arrays.asList(data1);
    Call<Result> method1Call = service.method1(array1);
    
    // Use the second method.
    Integer[] data2 = new Integer[]{0,1,3,5};
    Integer[][] array2 = new Integer[][]{data2};
    Call<Result> method2Call = service.method2(array2);
    
    // Execute enqueue() or execute() of method1Call or method2Call.
    

Please refer to the code ParameterHandler.java of Retrofit2 for the reason why the way can solve the problem.

Upvotes: 0

Jay
Jay

Reputation: 694

Well this did the trick for me

Step 1 :

In StateServce.kt

@GET("states/v1")
fun getStatesByCoordinates(@Query("coordinates", encoded = true) coordinates: String) : Call<ApiResponse<List<State>>>

Step 2

While calling from repository

val mCoordinate : List<Double> = [22.333, 22.22]
mStateService?.getStatesByCoordinates(mCoordinate.toString().replace(" ", ""))!!

Upvotes: 1

mrstif
mrstif

Reputation: 2946

You need to name your query param with an array syntax like so:

@GET("http://server/service")
Observable<Void> getSomething(@Query("array[]") List<Integer> array);

The syntax itself will vary by the backend technology being used, however not including the brackets "[]" will normally be interpreted as a single value.

For example, using array=1&array=2 will generally be interpreted by backends as only array=1 or array=2 instead of array=[1,2].

Upvotes: 23

Sir Codesalot
Sir Codesalot

Reputation: 7293

Using toString didn't work for me. Instead, TextUtils.join(",", ids) does the trick.

Don't forget to mark the Query with encoded = true.

Upvotes: 3

jarora
jarora

Reputation: 5762

I faced a similar problem and had to do a couple of things to reach the acceptable form (as asked in the question).

  1. Converted an ArrayList to String

    arrayList.toString().replace(" ", "")
    
  2. In RetroFit method, I changed the Query param which accepts the ArrayList above to as follows:

    @Query(value = "cities", encoded = true)
    

This ensures that the brackets and commas are not URL encoded.

Upvotes: 5

Fran&#231;ois Legrand
Fran&#231;ois Legrand

Reputation: 1233

I have finally founded a solution by using Arrays.toString(int []) method and by removing spaces in this result because Arrays.toString return "[0, 1, 3, 5]". And my request method looks like this

@GET("http://server/service")
Observable<Void> getSomething(@Query("array") String array);

Upvotes: 9

Andrej Jurkin
Andrej Jurkin

Reputation: 2266

Just add it as a query param

@GET("http://server/service")
Observable<Void> getSomething(@Query("array") List<Integer> array);

You can also use int[], or Integer... as a last param;

Upvotes: 21

Related Questions