2

我只是在学习 Retrofit 和 OKHttp,现在我有一个问题。我的应用程序中的每个请求都是 POST,就像这样:

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

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

然后我认为 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();

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

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

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

4

2 回答 2

3

好的......最后我找到了一种方法来做到这一点。但我不确定这是最好的方法。

这是代码:

    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 请求都有“帐户”和“令牌”。

如果有更好的方法来做到这一点,请告诉我。

于 2016-04-21T02:01:21.957 回答
1

你可以通过向 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);
    }
});
于 2019-09-22T07:42:52.663 回答