2016-01-14 84 views
15

我在Android應用程序中使用OkHttp客戶端進行Retrofit 2(2.0.0-beta3),至此一切進展順利。但是目前我正面臨着OkHttp攔截器的問題。我與之通信的服務器是在請求體中使用訪問令牌,所以當我需要添加auth令牌時,我攔截添加auth令牌的請求或Authenticator的身份驗證方法時,需要修改此請求的主體。但它看起來像我只能在標題中添加數據,而不是在正在進行的請求中添加數據。到目前爲止,我寫的代碼如下:Retrofit2:修改OkHttp攔截器中的請求體

client.interceptors().add(new Interceptor() { 
      @Override 
      public Response intercept(Chain chain) throws IOException { 
       Request request = chain.request(); 
       if (UserPreferences.ACCESS_TOKEN != null) { 
        // need to add this access token in request body as encoded form field instead of header 
        request = request.newBuilder() 
          .header("access_token", UserPreferences.ACCESS_TOKEN)) 
          .method(request.method(), request.body()) 
          .build(); 
       } 
       Response response = chain.proceed(request); 
       return response; 
      } 
     }); 

任何人都可以點我朝着正確的方向如何修改請求身體補充我的訪問令牌(首次或令牌刷新後更新)?任何指向正確的方向將不勝感激。

回答

16

我用它來添加post參數到現有的參數。

OkHttpClient client = new OkHttpClient.Builder() 
        .protocols(protocols) 
        .addInterceptor(new Interceptor() { 
         @Override 
         public Response intercept(Chain chain) throws IOException { 
          Request request = chain.request(); 
          Request.Builder requestBuilder = request.newBuilder(); 
RequestBody formBody = new FormEncodingBuilder() 
      .add("email", "[email protected]") 
      .add("tel", "90301171XX") 
      .build(); 
          String postBodyString = Utils.bodyToString(request.body()); 
          postBodyString += ((postBodyString.length() > 0) ? "&" : "") + Utils.bodyToString(formBody); 
          request = requestBuilder 
            .post(RequestBody.create(MediaType.parse("application/x-www-form-urlencoded;charset=UTF-8"), postBodyString)) 
            .build(); 
          return chain.proceed(request); 
         } 
        }) 
        .build(); 

public static String bodyToString(final RequestBody request){ 
     try { 
      final RequestBody copy = request; 
      final Buffer buffer = new Buffer(); 
      if(copy != null) 
       copy.writeTo(buffer); 
      else 
       return ""; 
      return buffer.readUtf8(); 
     } 
     catch (final IOException e) { 
      return "did not work"; 
     } 
    } 

OkHttp3:

RequestBody formBody = new FormBody.Builder() 
       .add("email", "[email protected]") 
       .add("tel", "90301171XX") 
       .build(); 
+0

這將是一個好主意,關閉緩存在'bodyToString()'返回 –

+0

@ 3K那不是需要之前,緩衝犯規分配任何可以在構造函數中被關閉。 https://github.com/square/okio/blob/master/okio/src/main/java/okio/Buffer.java#L59 – Fabian

1

因爲這不能被寫入由@Fabian以前的答案的意見,我張貼這一個作爲單獨的答案。這個答案處理「application/json」以及表單數據。

import android.content.Context; 

import org.json.JSONException; 
import org.json.JSONObject; 

import java.io.IOException; 

import okhttp3.FormBody; 
import okhttp3.Interceptor; 
import okhttp3.MediaType; 
import okhttp3.Request; 
import okhttp3.RequestBody; 
import okhttp3.Response; 
import okio.Buffer; 

/** 
* Created by debanjan on 16/4/17. 
*/ 

public class TokenInterceptor implements Interceptor { 
    private Context context; //This is here because I needed it for some other cause 

    //private static final String TOKEN_IDENTIFIER = "token_id"; 
    public TokenInterceptor(Context context) { 
     this.context = context; 
    } 

    @Override 
    public Response intercept(Chain chain) throws IOException { 
     Request request = chain.request(); 
     RequestBody requestBody = request.body(); 
     String token = "toku";//whatever or however you get it. 
     String subtype = requestBody.contentType().subtype(); 
     if(subtype.contains("json")){ 
      requestBody = processApplicationJsonRequestBody(requestBody, token); 
     } 
     else if(subtype.contains("form")){ 
      requestBody = processFormDataRequestBody(requestBody, token); 
     } 
     if(requestBody != null) { 
      Request.Builder requestBuilder = request.newBuilder(); 
      request = requestBuilder 
        .post(requestBody) 
        .build(); 
     } 

     return chain.proceed(request); 
    } 
    private String bodyToString(final RequestBody request){ 
     try { 
      final RequestBody copy = request; 
      final Buffer buffer = new Buffer(); 
      if(copy != null) 
       copy.writeTo(buffer); 
      else 
       return ""; 
      return buffer.readUtf8(); 
     } 
     catch (final IOException e) { 
      return "did not work"; 
     } 
    } 
    private RequestBody processApplicationJsonRequestBody(RequestBody requestBody,String token){ 
     String customReq = bodyToString(requestBody); 
     try { 
      JSONObject obj = new JSONObject(customReq); 
      obj.put("token", token); 
      return RequestBody.create(requestBody.contentType(), obj.toString()); 
     } catch (JSONException e) { 
      e.printStackTrace(); 
     } 
     return null; 
    } 
    private RequestBody processFormDataRequestBody(RequestBody requestBody, String token){ 
     RequestBody formBody = new FormBody.Builder() 
       .add("token", token) 
       .build(); 
     String postBodyString = bodyToString(requestBody); 
     postBodyString += ((postBodyString.length() > 0) ? "&" : "") + bodyToString(formBody); 
     return RequestBody.create(requestBody.contentType(), postBodyString); 
    } 

}