2016-01-14 14 views
15

Android uygulamasında OkHttp istemcisiyle birlikte Retrofit 2 (2.0.0-beta3) kullanıyorum ve şu ana kadar her şey yolunda gidiyor. Ancak şu anda OkHttp Interceptor ile sorun yaşıyorum. Iletisim kurduğum sunucu istek gövdesinde erişim belirtecini almaktır, bu yüzden auth jetonu ekleme talebini engellediğimde veya güncellenmiş auth jetonu eklemem gerektiğinde Authenticator yönteminin kimlik doğrulaması yapıldığında, bu amaçla istek gövdesini değiştirmem gerekir. . Fakat sadece başlıklara veri ekleyebiliyorum ama devam eden talebin gövdesinde değil gibi görünüyor.Retrofit2: OkHttp Interceptor'da istek gövdesini değiştirme

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; 
      } 
     }); 

kimse benim erişim belirteci (ilk defa veya belirteç yenilemeden sonra güncellenir) eklemek için istek gövdesini nasıl değiştirileceğini olarak doğru yöne işaret edebilir şöyledir: Şimdiye kadar yazdım kodudur? Doğru yöne herhangi bir işaretçi takdir edilecektir.

cevap

16

Bunu, varolanlara post parametresi eklemek için kullanıyorum.

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: Bu yana

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

o() ' –

+0

3k @ Thats gerekli değildir dönmeden önce, Tampon kurucu içinde kapatılabilir bir şey tahsis doesnt bodyToString' de tampon kapatmak için iyi bir fikir olacaktır. https://github.com/square/okio/blob/master/okio/src/main/java/okio/Buffer.java#L59 – Fabian

1

@Fabian önceki cevap yorumlarında yazılamaz, ben ayrı cevap olarak bu bir ilanıyla. Bu cevap, hem "uygulama/json" hem de form verileriyle ilgilidir.

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); 
    } 

}