Java 有没有办法使用 Retrofit 2 向每个请求添加查询参数?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32948083/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to add query parameter to every request with Retrofit 2?
提问by Max
I need to add a query parameter to every request made by Retrofit 2.0.0-beta2 library. I found this solutionfor Retrofit 1.9, but how to add RequestInterceptor
in newest library version?
我需要为 Retrofit 2.0.0-beta2 库发出的每个请求添加一个查询参数。我为 Retrofit 1.9找到了这个解决方案,但是如何添加RequestInterceptor
最新的库版本?
My interface:
我的界面:
@GET("user/{id}")
Call<User> getUser(@Path("id")long id);
@GET("users/")
Call<List<User>> getUser();
Client:
客户:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(CLIENT) // custom OkHTTP Client
.build();
service = retrofit.create(userService.class);
采纳答案by Lukas Lechner
For the sake of completeness, here is the full code you need to add a parameter to every Retrofit 2.x request using a OkHttp-Interceptor:
为了完整起见,这里是使用 OkHttp-Interceptor 向每个 Retrofit 2.x 请求添加参数所需的完整代码:
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
HttpUrl url = request.url().newBuilder().addQueryParameter("name","value").build();
request = request.newBuilder().url(url).build();
return chain.proceed(request);
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("...")
.client(client)
.build();
回答by sebastian
You have to switch to an Interceptor
from OkHttp
. Create an OkHttpClient
, add the Interceptor
to it an pass that client in the Retrofit Builder
.
您必须切换到Interceptor
from OkHttp
。创建一个OkHttpClient
,Interceptor
在 Retrofit 中添加一个传递给它的客户端Builder
。
OkHttpClient client = new OkHttpClient();
client.interceptors().add(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
...
}
});
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("...")
.client(client)
.build();
You can then adjust the request to your needs using chain.request().newBuilder()
. See the documentationfor details.
然后,您可以使用 调整请求以满足您的需要chain.request().newBuilder()
。有关详细信息,请参阅文档。
回答by zenghui.wang
now the Retrofit has release 2.0.0 and this is my solution:
现在 Retrofit 发布了 2.0.0,这是我的解决方案:
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
String uid = "0";
long timestamp = (int) (Calendar.getInstance().getTimeInMillis() / 1000);
String signature = MD5Util.crypt(timestamp + "" + uid + MD5_SIGN);
String base64encode = signature + ":" + timestamp + ":" + uid;
base64encode = Base64.encodeToString(base64encode.getBytes(), Base64.NO_WRAP | Base64.URL_SAFE);
Request request = chain.request();
HttpUrl url = request.url()
.newBuilder()
.addQueryParameter("pageSize", "2")
.addQueryParameter("method", "getAliasList")
.build();
request = request
.newBuilder()
.addHeader("Authorization", "zui " + base64encode)
.addHeader("from_client", "ZuiDeer")
.url(url)
.build();
Response response = chain.proceed(request);
return response;
}
}).build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(ApiConstants.API_BASE_URL)
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.build();
mRestfulService = retrofit.create(RestfulService.class);
回答by Sergey Nikitin
In 3.2.0
and higher you should use addInterceptor()
in OkHttpClient.Builder
instead.
In3.2.0
及更高版本,您应该使用addInterceptor()
inOkHttpClient.Builder
代替。
For example, with Retrolambda
:
例如,使用Retrolambda
:
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor()
.setLevel(HttpLoggingInterceptor.Level.BASIC);
Interceptor clientInterceptor = chain -> {
Request request = chain.request();
HttpUrl url = request.url().newBuilder().addQueryParameter("name", "value").build();
request = request.newBuilder().url(url).build();
return chain.proceed(request);
};
OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(clientInterceptor)
.addInterceptor(loggingInterceptor)
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.client(client)
.build();
回答by isakbob
A lot of these answers are similar, but an issue I came accross is the chaining of functions inside the Interceptor
which led it to fail for me. Changes cannot be made directly to a urlaccording to the linked video. Rather, a copy of the url must be made and then reassigned back to the original url as shown below:
这些答案中有很多是相似的,但我遇到的一个问题是里面的函数链接Interceptor
导致它对我来说失败了。无法根据链接的视频直接更改网址。相反,必须制作 url 的副本,然后重新分配回原始 url,如下所示:
{
{
public method(){
final String api_key = "key";
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
HttpUrl httpUrl = original.url();
HttpUrl newHttpUrl = httpUrl
.newBuilder()
.addQueryParameter("api_key", api_key)
.build();
Request.Builder requestBuilder = original
.newBuilder()
.url(newHttpUrl);
Request request = requestBuilder
.build();
return chain.proceed(request);
}
}).build();
retrofit = new Retrofit.Builder()
.baseUrl("https://base.url.ext/")
.client(client)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
While the functions called are identical to the first answer, this answer partitions the function calls out. Namely, the original url as well as the new url are stored in separate local variables. This prevents overwriting the original url until you want the OkHttpClient
to do so.
虽然调用的函数与第一个答案相同,但此答案将函数调用分开。即,原始 url 和新 url 存储在单独的局部变量中。这可以防止覆盖原始 url,直到您想OkHttpClient
要这样做。
回答by Achraf Amil
In kotlin, add the following interceptor to the OkHttpClient you set in Retrofit builder :
在 kotlin 中,将以下拦截器添加到您在 Retrofit builder 中设置的 OkHttpClient 中:
Retrofit.Builder()
.baseUrl("...")
.client(
OkHttpClient.Builder()
.addInterceptor { chain ->
val url = chain
.request()
.url()
.newBuilder()
.addQueryParameter("key", "value")
.build()
chain.proceed(chain.request().newBuilder().url(url).build())
}
.build()
)
.build()
.create(FooService::class.java)
And, of course, extracting the OkHttpClient building into a val or an injection dependency would make it even more modular and lisible.
而且,当然,将 OkHttpClient 构建提取到 val 或注入依赖项中会使其更加模块化和可靠。