2016-01-14 49 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); 
    } 

}