2017-03-21 74 views
1

作为@Query注释上面the Retrofit documentation指出:更改列表/阵列的URL格式为[改造2]

传递一个列表或阵列将导致在每个 非空条目的查询参数。


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

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

这工作,但结果相当长的URL相当快。

E.g.对于excludedQuestionIds = new long[]{1L, 4L, 16L, 64L}请求URL已经是/questions?exclude_ids=1&exclude_ids=4&exclude_ids=16&exclude_ids=64


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

什么来到我的脑海里又是到:

  • 使用JsonArray作为参数,但后来我需要打出电话
  • 截获每个请求之前,每个阵列/列表转换和压缩重复键
  • 覆盖内置@Query装饰

任何想法?

回答

0

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

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解决方案

文本实用程序是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了解有关串联更多的解决方案。