web-dev-qa-db-ja.com

Androidパラメータ化された@Headersのレトロフィット

OAuthを使用しており、リクエストを行うたびにヘッダーにOAuthトークンを挿入する必要があります。 @Header注釈が表示されますが、実行時に渡すことができるようにパラメーター化する方法はありますか?

ここにコンセプトがあります

@Header({Authorization:'OAuth {var}', api_version={var} })

ランタイムでそれらを渡すことができますか?

@GET("/users")
void getUsers(
    @Header("Authorization") String auth, 
    @Header("X-Api-Version") String version, 
    Callback<User> callback
)
77
jpotts18

@Headerパラメーターを使用する以外に、RequestInterceptorを使用して、インターフェイスを変更せずにすべてのリクエストを更新します。次のようなものを使用します。

RestAdapter.Builder builder = new RestAdapter.Builder()
    .setRequestInterceptor(new RequestInterceptor() {
        @Override
        public void intercept(RequestFacade request) {
            request.addHeader("Accept", "application/json;versions=1");
            if (isUserLoggedIn()) {
                request.addHeader("Authorization", getToken());
            }                    
        }
    });

p/s:Retrofit2を使用している場合、Interceptorの代わりにRequestInterceptorに気付くはずです。

RequestInterceptorはRetrofit 2.0では使用できなくなったため

92
Felix

はい、実行時に渡すことができます。実際のところ、あなたがそれをタイプしたのとほぼ同じです。これは、saySecretApiInterface.Javaという名前のAPIインターフェイスクラスにあります。

public interface SecretApiInterface {

    @GET("/secret_things")
    SecretThing.List getSecretThings(@Header("Authorization") String token)

}

次に、これらの行に沿って、リクエストからこのインターフェイスにパラメーターを渡します:(このファイルは、たとえばSecretThingRequest.Java

public class SecretThingRequest extends RetrofitSpiceRequest<SecretThing.List, SecretApiInteface>{

    private String token;

    public SecretThingRequest(String token) {
        super(SecretThing.List.class, SecretApiInterface.class);
        this.token = token;
    }

    @Override
    public SecretThing.List loadDataFromNetwork() {
        SecretApiInterface service = getService();
        return service.getSecretThings(Somehow.Magically.getToken());
    }
}

Somehow.Magically.getToken()がトークンを返すメソッド呼び出しである場合、トークンをどこでどのように定義するかはユーザー次第です。

もちろん、あなたの場合のように、インターフェース実装に複数の@Header("Blah") String blah注釈を付けることができます!

私もそれが混乱していることに気付きました、ドキュメントは明確にそれを言いますreplacesヘッダーですが、それはDOES N'T
実際には@Headers("hardcoded_string_of_liited_use")アノテーションと同様に追加されます

お役に立てれば ;)

51
nana

受け入れられる答えは、Retrofitの古いバージョンに対するものです。将来の視聴者のために、Retrofit 2.0でこれを行う方法は、カスタムOkHttpクライアントを使用しています。

OkHttpClient httpClient = new OkHttpClient.Builder()
  .addInterceptor(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException {
      Builder ongoing = chain.request().newBuilder();
      ongoing.addHeader("Accept", "application/json;versions=1");
      if (isUserLoggedIn()) {
        ongoing.addHeader("Authorization", getToken());
      }
      return chain.proceed(ongoing.build());
    }
  })
  .build();

Retrofit retrofit = new Retrofit.Builder()
  // ... extra config
  .client(httpClient)
  .build();

それが誰かを助けることを願っています。 :)

34
pablisco

レトロフィット2.3.0

OkHttpClient.Builder okHttpClientBuilder = new OkHttpClient.Builder();
    okHttpClientBuilder
            .addInterceptor(new Interceptor() {
                @Override
                public okhttp3.Response intercept(Chain chain) throws IOException {
                    Request request = chain.request();
                    Request.Builder newRequest = request.newBuilder().header("Authorization", accessToken);
                    return chain.proceed(newRequest.build());
                }
            });

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(GithubService.BASE_URL)
            .client(okHttpClientBuilder.build())
            .addConverterFactory(GsonConverterFactory.create())
            .build();

これを使用してGitHubに接続しています。

5
Soon Santos