28

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 ?

1
  • did it work on postman? Commented Jan 11, 2017 at 12:05

8 Answers 8

23

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].

Sign up to request clarification or add additional context in comments.

4 Comments

Doesn't work for me. https:/server/service?array[]=value1&array[]=value2 is what I get
That's exactly what you should get @Przemo
@mrstif I thought the questions is about getting array=[1,2], not array[]=value1&array[]=value2.
@XiWei as my answer states that is in fact how most servers normally interpret those values
21

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;

3 Comments

I have tried this solution but the generated url looks like this : server/service?array=0&array=1&array=3&array=5 but i my case I'm looking for a way to get a generated url which looks like this server/service?array=[0,1,3,5]
now that is a not very standard way to go. you can try server.service?array=[{array}] and in request use @Path("array") String and feed it with generated string from you array. But I'm not sure if this can go through the Retrofit. Alternatively you can try push it as a query param. @Query("array) and generate the String that you need manually in your case "[1,2,3]"
@AndrejJurkin The way using @path cannot go through the Retrofit: java.lang.IllegalArgumentException: URL query string "array={array}" must not have replace block. For dynamic query parameters use @Query.
9

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);

1 Comment

This doesn't work when you're int[] has space between elements. Also your server should should support that param in string.
5

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.

Comments

3

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

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

Comments

1

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(" ", ""))!!

Comments

0

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.

Comments

0

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.

Comments

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.