如 the Retrofit documentation 中所述在 @Query
注释之上:
Passing a List or array will result in a query parameter for each non-null item.
到目前为止,我的电话看起来像这样:
@GET("questions")
Call<List<QuestionHolder>> getQuestionsExcludingTheSpecified(
@Query("exclude_ids") long[] excludedQuestionIds
);
这行得通,但会很快生成相当长的 URL。
例如对于 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 作为参数,但我需要在调用之前转换每个数组/列表
- 拦截每个请求并压缩重复的 key
- 覆盖内置的
@Query
装饰器
有什么想法吗?
最佳答案
我决定采用拦截器方法。我只需更改任何包含单个查询参数的多个值的传出请求。
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);
}
非安卓解决方案
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有关串联的更多解决方案。
关于java - 更改 URL 中列表/数组的格式 [Retrofit 2],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42938074/