2015-10-06 7 views
51

にヘッダを追加するインターセプタを使用する方法私たちのチームは、レトロフィット2.0を採用することを決定し、私はそれにいくつかの初期の研究をやっています。私はこのライブラリに初心者だとタイトルに記載されているように、コミュニティ:)レトロフィット2.0

からいくつかの助けを得るために願って、私たちのAndroidアプリに改修2.0を経由してカスタマイズされたヘッダを追加するinterceptorを使用する方法を思ったんだけど。 Retrofit 1.Xにはヘッダを追加するのにが多くありますが、APIが最新バージョンで大きく変更されているため、新しいバージョンでこれらのメソッドをどのように適応させるかはわかりません。また、Retrofitはまだ新しいドキュメントを更新していません。

たとえば、次のコードでは、どのように私は、余分なヘッダを追加するInterceptorクラスを実装する必要がありますか?また、undocumented Chain objectとは何ですか? intercept()はいつ呼び出されますか?

OkHttpClient client = new OkHttpClient(); 
    client.interceptors().add(new Interceptor() { 
     @Override 
     public Response intercept(Chain chain) throws IOException { 
      Response response = chain.proceed(chain.request()); 

      // How to add extra headers? 

      return response; 
     } 
    }); 

    Retrofit retrofit = new Retrofit.Builder() 
      .baseUrl(BASE_API_URL) 
      .client(client) 
      .addConverterFactory(GsonConverterFactory.create()) 
      .build(); 

誰でもこの問題に関するアイデアを共有できますか?

ありがとうございます!

+1

のようにそのビルトインメソッドを持つインターセプタを使用してヘッダーをあなたのBASE_API_URLは '/'とし、 '(あなたのAPIのURLがないことを終了していることを確認してくださいすることができます物事/投稿/何でも ') – EpicPandaForce

答えて

60

これをチェックしてください。

public class HeaderInterceptor 
     implements Interceptor { 
    @Override 
    public Response intercept(Chain chain) 
      throws IOException { 
     Request request = chain.request(); 
     request = request.newBuilder() 
       .addHeader("appid", "hello") 
       .addHeader("deviceplatform", "android") 
       .removeHeader("User-Agent") 
       .addHeader("User-Agent", "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:38.0) Gecko/20100101 Firefox/38.0") 
       .build(); 
     Response response = chain.proceed(request); 
     return response; 
    } 
} 
+0

ありがとう!!したがって、アプリケーションから要求が送信されるたびにこの 'intercept()'がトリガされます。リダイレクトの中間応答を捕まえることはできますか、それとも単に最終応答を得ることができますか? – hackjutsu

+0

これはリクエストごとに呼び出されます。私が正しいと分かっているのは、ネットワークインターセプタではなく、インターセプタとして追加するからです。私はここで最終的な応答しか得られないと思いますが、リダイレクトを私の頭の上からわからないリダイレクトとして見ることができる設定があるかもしれません(HTTP URL接続用にもあります)。 – EpicPandaForce

+1

ちょうど参照してくださいこのリンク:https://github.com/square/okhttp/wiki/Interceptors、と私は:)は〜 – hackjutsu

15

別の代替accepted answer

public class HeaderInterceptor implements Interceptor { 

    @Override 
    public Response intercept(Chain chain) throws IOException { 
     Request request = chain.request(); 

     request = request.newBuilder() 
       .addHeader("headerKey0", "HeaderVal0") 
       .addHeader("headerKey0", "HeaderVal0--NotReplaced/NorUpdated") //new header added 
       .build(); 

     //alternative 
     Headers moreHeaders = request.headers().newBuilder() 
       .add("headerKey1", "HeaderVal1") 
       .add("headerKey2", "HeaderVal2") 
       .set("headerKey2", "HeaderVal2--UpdatedHere") // existing header UPDATED if available, else added. 
       .add("headerKey3", "HeaderKey3") 
       .add("headerLine4 : headerLine4Val") //line with `:`, spaces doesn't matter. 
       .removeAll("headerKey3") //Oops, remove this. 
       .build(); 

     request = request.newBuilder().headers(moreHeaders).build(); 

     /* ##### List of headers ##### */ 
     // headerKey0: HeaderVal0 
     // headerKey0: HeaderVal0--NotReplaced/NorUpdated 
     // headerKey1: HeaderVal1 
     // headerKey2: HeaderVal2--UpdatedHere 
     // headerLine4: headerLine4Val 

     Response response = chain.proceed(request); 
     return response; 
    } 
} 
+0

Nice! 'request.newBuilder().headers(moreHeaders).build()'は元のヘッダを保持しますか? – hackjutsu

+1

はい。 [removeAll(String name)](http://square.github.io/okhttp/javadoc/com/squareup/okhttp/Headers.Builder.html#removeAll-java.lang.String-)を除き、要求からヘッダーは削除されません。が呼び出されます。 – VenomVendor

+0

@VenomVendorここで似たような質問をしてください。https://stackoverflow.com/questions/45078720/dagger-generating-multiple-instances-of-retrofit-interceptor ありがとう – user606669

3
public class ServiceFactory { 
    public static ApiClient createService(String authToken, String userName, String password) { 
      OkHttpClient defaultHttpClient = new OkHttpClient.Builder() 
        .addInterceptor(
          chain -> { 
           Request request = chain.request().newBuilder() 
             .headers(getJsonHeader(authToken)) 
             .build(); 
           return chain.proceed(request); 
          }) 
        .authenticator(getBasicAuthenticator(userName, password)) 
        .build(); 
      return getService(defaultHttpClient); 
     } 
     private static Headers getJsonHeader(String authToken) { 
      Headers.Builder builder = new Headers.Builder(); 
      builder.add("Content-Type", "application/json"); 
      builder.add("Accept", "application/json"); 
      if (authToken != null && !authToken.isEmpty()) { 
       builder.add("X-MY-Auth", authToken); 
      } 
      return builder.build(); 
     } 
     private static Authenticator getBasicAuthenticator(final String userName, final String password) { 
      return (route, response) -> { 
       String credential = Credentials.basic(userName, password); 
       return response.request().newBuilder().header("Authorization", credential).build(); 
      }; 
     } 
      private static ApiClient getService(OkHttpClient defaultHttpClient) { 
      return new Retrofit.Builder() 
        .baseUrl(BASE_URL) 
        .addConverterFactory(GsonConverterFactory.create()) 
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create()) 
        .client(defaultHttpClient) 
        .build() 
        .create(ApiClient.class); 
     } 
} 
0

あなたはこの

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

      Request.Builder builder = original.newBuilder(); 

      builder.header("Authorization","Bearer "+ LeafPreference.getInstance(context).getString(LeafPreference.TOKEN)); 

      Request request = builder.method(original.method(), original.body()) 
        .build(); 
      Log.e("request",request.urlString()); 
      Log.e("header",request.header("Authorization")); 
      return chain.proceed(request); 
     } 
    }); 
} 
関連する問題