2015-11-06 50 views
3

到requestbody我有这:改造2追加后在截距

OkHttpClient client = new OkHttpClient(); 
client.interceptors().add(new Interceptor() { 
    @Override 
    public com.squareup.okhttp.Response intercept(Chain chain) throws IOException { 
     Request request = chain.request(); 
     HttpUrl url = request.httpUrl().newBuilder() 
        .addQueryParameter("platform", "android") 
        .addQueryParameter("app_version", com.package.BuildConfig.VERSION_NAME) 
        .build(); 
     Request newRequest = chain.request().newBuilder().url(url).build(); 
     return chain.proceed(newRequest); 
    } 
}); 

但还要额外交键值附加到包含用户钥请求主体。这看起来像

RequestBody newBody = RequestBody.create(request.body().contentType(),request.body().content+ request.addPost("sUserKey","3254345kdskf"); 
... 
... 
Request newRequest = chain.request() 
.newBuilder() 
.url(url) 
.post(newBody) 
.build(); 
+0

有什么问题,怎么做呢? – Blackbelt

+0

在okhttp拦截过程中,您将如何添加额外的POST? –

+0

你想要对不同的端点发布post请求吗? – Blackbelt

回答

2

你可以做到这一点,而无需创建额外的类。

client.interceptors().add(new Interceptor() { 
    @Override 
    public com.squareup.okhttp.Response intercept(Chain chain) throws IOException { 
     Request request = chain.request(); 
     String parameter = "&" + name + "=" + value; 
     Request newRequest = interceptRequest(request, parameter) 
     return chain.proceed(newRequest); 
    } 
}); 

这是创建新请求的简单方法。

public static Request interceptRequest(@NotNull Request request, @NotNull String parameter) 
      throws IOException { 

     ByteArrayOutputStream baos = new ByteArrayOutputStream(); 

     Sink sink = Okio.sink(baos); 
     BufferedSink bufferedSink = Okio.buffer(sink); 

     /** 
     * Write old params 
     * */ 
     request.body().writeTo(bufferedSink); 

     /** 
     * write to buffer additional params 
     * */ 
     bufferedSink.writeString(parameter, Charset.defaultCharset()); 

     RequestBody newRequestBody = RequestBody.create(
       request.body().contentType(), 
       bufferedSink.buffer().readUtf8() 
     ); 

     return request.newBuilder().post(newRequestBody).build(); 
    } 

您也可以从Gist

5

追加到RequestBody不是直截了当的。这里是一个自定义RequestBody的草图,它将添加一个post参数。几个警告 - 你会想添加一些错误检查,如确保现有的身体不为空。给定的代码还假定所有来这个拦截器的调用都是POST。如果不是这种情况,则在应用新正文之前,您需要检查传入的请求类型。另外,由于这只是将新参数复制到主体中,所以如果需要,您需要确保名称和主体已经被url编码。

class AddPostParamRequestBody extends RequestBody { 

    final RequestBody body; 
    final String parameter; 

    AddPostParamRequestBody(RequestBody body, String name, String value) { 
     this.body = body; 
     this.parameter = "&" + name + "=" + value; 
    } 

    @Override 
    public long contentLength() throws IOException { 
     return body.contentLength() + parameter.length(); 
    } 

    @Override 
    public MediaType contentType() { 
     return body.contentType(); 
    } 

    @Override 
    public void writeTo(BufferedSink bufferedSink) throws IOException { 
     body.writeTo(bufferedSink); 
     bufferedSink.writeString(parameter, Charset.forName("UTF-8")); 
    } 

} 

然后你就可以在你的拦截器使用 -

client.interceptors().add(new Interceptor() { 
    @Override 
    public com.squareup.okhttp.Response intercept(Chain chain) throws IOException { 
     Request request = chain.request(); 
     HttpUrl url = request.httpUrl().newBuilder().addQueryParameter("added", "param").build(); 
     AddPostParamRequestBody newBody = new AddPostParamRequestBody(request.body(), "sUserKey","3254345kdskf"); 
     Request newRequest = request.newBuilder().post(newBody).url(url).build(); 
     return chain.proceed(newRequest); 
    } 
}); 

你的另一种选择是将包括在您的改装定义一个额外的Field注释,并通过它在每次通话,但我相信你试图避免这种情况。