更改URL [Retrofit 2]中列表/数组的格式

时间:2017-03-21 21:02:55

标签: java android http retrofit2

@Query注释中的the Retrofit documentation所述:

  

传递List或数组将导致每个查询参数   非空项目。

截至目前,我的电话看起来像这样:

@GET("questions")
Call<List<QuestionHolder>> getQuestionsExcludingTheSpecified(
        @Query("exclude_ids") long[] excludedQuestionIds
);

这样可以很快地生成相当长的URL。

E.g。对于excludedQuestionIds = new long[]{1L, 4L, 16L, 64L},请求网址已为/questions?exclude_ids=1&exclude_ids=4&exclude_ids=16&exclude_ids=64

是否有一种简单的方法来交换此行为,从而导致数组格式为exclude_ids=[1,4,16,64]或类似的东西?

我想到的是:

  • 使用JsonArray作为参数,但是我需要在调用之前转换每个数组/列表
  • 拦截每个请求并压缩重复的密钥
  • 覆盖内置的@Query装饰器

有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我决定采用Interceptor方法。我只是更改任何包含单个查询参数的多个值的传出请求。

public class QueryParameterCompressionInterceptor implements Interceptor {

    @Override
    public Response intercept(Interceptor.Chain chain) throws IOException {
        Request request = chain.request();

        HttpUrl url = request.url();
        for (String parameterName : url.queryParameterNames()) {
            List<String> queryParameterValues = url.queryParameterValues(parameterName);

            if (queryParameterValues.size() > 1) {
                String formattedValues= "[" + TextUtils.join(",", queryParameterValues) + "]";

                request = request.newBuilder()
                        .url(
                                url.newBuilder()
                                        .removeAllQueryParameters(parameterName)
                                        .addQueryParameter(parameterName, formattedValues)
                                        .build()
                        ).build();
            }
        }

        return chain.proceed(request);
    }

非Android解决方案

TextUtils是Android SDK的一部分,如果您不是为Android开发,您可以将TextUtils.join替换为这样的方法:

    public static String concatListOfStrings(String separator, Iterable<String> strings) {
        StringBuilder sb = new StringBuilder();

        for (String str : strings) {
            sb.append(separator).append(str);
        }

        sb.delete(0, separator.length());

        return sb.toString();
    }
}

您还可以查看this SO question以获取有关串联的更多解决方案。