2015-10-07 51 views
1

到目前爲止,我一直在使用OkHttp來處理我的網絡請求,但現在我想要使用Retrofit(v2)。 我與之通信的服務器要求AuthToken作爲Url(GET請求)的一部分或Body(POST請求)的一部分。 我還需要將請求創建與執行分開,這是一個很好的改進功能,即我可以傳遞Call對象並稍後執行/排隊。使用Retrofit/OkHttp修改POST請求正文

最難的部分是AuthToken在創建請求時可能不可用,我需要在它執行之前對其進行修改。到目前爲止,我一直在創建時添加一個虛擬authToken,並在執行之前進行替換。 對於GET請求,這非常簡單,因爲我可以將Interceptor添加到OkHttpClient中來修改請求Url,但修改POST請求的正文是我努力的事情。

那麼,在Retrofit/OkHttp中是否支持這個用例呢? java.lang.IllegalStateException:

一些沒有工作的示例代碼,幾乎會做的伎倆(嘗試添加的authToken總是可用的時候,用結束!無分塊編碼或已知的內容長度不能流的請求體

client.networkInterceptors().add(new Interceptor() { 
     @Override 
     public Response intercept(Chain chain) throws IOException { 
      Request request = chain.request(); 

      if (request.body() == null) { 
       return chain.proceed(request); 
      } 

      Request authorizedRequest = request.newBuilder() 
        .method(request.method(), replaceDummyAuth(request.body())) 
        .build(); 
      return chain.proceed(authorizedRequest); 
     } 

     private RequestBody replaceDummyAuth(final RequestBody body) { 
      return new RequestBody() { 
       @Override 
       public MediaType contentType() { 
        return body.contentType(); 
       } 

       @Override 
       public long contentLength() throws IOException { 
        return -1; 
       } 

       @Override 
       public void writeTo(BufferedSink sink) throws IOException { 
        ParametersMap map = new ParametersMap(); 

        BufferedSink authSink = Okio.buffer(sink); 
        body.writeTo(authSink); 

        String authToken = SessionManager.getAuthToken(); 
        if(StringUtils.hasText(authToken)) { 
         map.put("authToken", authToken); 
         String paramString = map.getParameterString(); 
         authSink.write(paramString.getBytes("UTF-8")); 
        } 
        authSink.close(); 
       } 
      }; 
     } 
    }); 
+0

爲什麼內容長度爲-1?難道gzip壓縮? –

+0

不,這不是gzipped,我只是不知道如何實現contentLength()。如果我把:return body.contentLength();我ge t「java.net.ProtocolException:期望的0字節但收到111」 – pmellaaho

回答