如何在每个帖子中使用Retrofit和OKHttp添加默认参数

时间:2016-04-20 09:25:03

标签: android retrofit2 okhttp3

我正在学习Retrofit和OKHttp,现在我遇到了问题。 我的应用中的每个请求都是POST,就像这样:

@FormUrlEncoded
@POST("some url")
Observable<Result> getData(@Field("id") String id);

在每个POST中,都有两个相同的参数。因此,以最简单的方式,我可以在每个方法中添加两个@Field,例如@Field(&#34; token&#34;),@ Field(&#34; account&#34;)。但我认为必须有一种聪明的方式。

然后我认为OkHttpClient可以解决这个问题。

OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            RequestBody body = new FormBody.Builder().add("account", "me")
                    .add("token", "123456").build();
            request = request.newBuilder().post(body).build();
            return chain.proceed(request);
        }
    }).build();
Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("some base url")
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();

或者

HttpUrl url = request.url().newBuilder()
                    .setEncodedQueryParameter("account", "me")
                    .setEncodedQueryParameter("token", "123456")
                    .build();

第一种方法只是将所有Field替换为这两种。

第二种方法只是将这两个添加为GET参数,而不是POST。

现在我完全不知道如何做这项工作。

2 个答案:

答案 0 :(得分:2)

好的......最后我找到了办法。但我不确定这是最好的方式。

以下是代码:

    OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            FormBody.Builder bodyBuilder = new FormBody.Builder();
            FormBody b = (FormBody) request.body();
            for (int i=0;i<b.size();i++) {
                bodyBuilder.addEncoded(b.name(i),b.value(i));
            }
            bodyBuilder.addEncoded("account", "me").add("token", "123456");
            request = request.newBuilder().post(bodyBuilder.build()).build();
            return chain.proceed(request);
        }
    }).build();
    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl("http://some url)
            .client(client)
            .addConverterFactory(GsonConverterFactory.create())
            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
            .build();

我从改造中获取所有@Field,然后将每个键值参数添加到新的RequestBody,与这两个默认参数相同。现在每个POST请求都有“account”和“token”。

如果有更好的方法,请告诉我。

答案 1 :(得分:0)

您可以通过向OkHttpClient添加新的请求拦截器来做到这一点。拦截实际的请求并获取HttpUrl。添加查询参数需要使用http url,因为它将通过附加查询参数名称及其值来更改以前生成的请求url。

OkHttpClient.Builder httpClient =  
    new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {  
    @Override
    public Response intercept(Chain chain) throws IOException {
        Request original = chain.request();
        HttpUrl originalHttpUrl = original.url();

        HttpUrl url = originalHttpUrl.newBuilder()
                .addQueryParameter("apikey", "your-actual-api-key")
                .build();

        // Request customization: add request headers
        Request.Builder requestBuilder = original.newBuilder()
                .url(url);

        Request request = requestBuilder.build();
        return chain.proceed(request);
    }
});