2016-01-14 6 views
15

AndroidアプリケーションでOkHttpクライアントでRetrofit 2(2.0.0-beta3)を使用しています。しかし、現在、私はOkHttpインターセプターの問題に直面しています。私が通信しているサーバーは要求の本文にアクセストークンを取っているので、認証トークンを追加する要求を傍受するか、更新された認証トークンを追加する必要があるときにオーセンティケータの認証メソッドで認証を要求すると、 。しかし、私はヘッダーにのみデータを追加できますが、進行中の要求の本文には追加できないようです。次のように私がこれまでに書いたコードは次のとおりです。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

それは() ' –

+0

3K @ザッツは必要ありませんを返す前に、バッファは、コンストラクタ内で閉じることができる何かを割り当てるdoesntのbodyToString'でバッファを閉じるには良いでしょう。 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); 
    } 

} 
関連する問題