Retrofit 2のドキュメント と言っています:
すべてのリクエストに追加する必要があるヘッダは、OkHttpインターセプタを使って指定できます。
それは以前のバージョンを使用して簡単に行うことができます ここに 関連するQA。
しかし、retrofit 2を使っても、Retrofit.Builder
オブジェクトに適用できるsetRequestInterceptor
やsetInterceptor
メソッドのようなものは見つかりませんでした。
また OkHttp にはRequestInterceptor
はもうないようです。 Retrofitのドキュメントでは Interceptor と書いてありますが、この目的のためにそれを使用する方法があまりよくわかっていませんでした。
これどうやってするの?
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("parameter", "value").build();
return chain.proceed(request);
}
});
Retrofit retrofit = new Retrofit.Builder().addConverterFactory(GsonConverterFactory.create()).baseUrl(url).client(httpClient.build()).build();
ラムダバージョン:
builder.addInterceptor(chain -> {
Request request = chain.request().newBuilder().addHeader("key", "value").build();
return chain.proceed(request);
});
醜い長いバージョン:
builder.addInterceptor(new Interceptor() {
@Override public Response intercept(Chain chain) throws IOException {
Request request = chain.request().newBuilder().addHeader("key", "value").build();
return chain.proceed(request);
}
});
フルバージョン:
class Factory {
public static APIService create(Context context) {
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.readTimeout(10, TimeUnit.SECONDS);
builder.connectTimeout(5, TimeUnit.SECONDS);
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BASIC);
builder.addInterceptor(interceptor);
}
builder.addInterceptor(chain -> {
Request request = chain.request().newBuilder().addHeader("key", "value").build();
return chain.proceed(request);
});
builder.addInterceptor(new UnauthorisedInterceptor(context));
OkHttpClient client = builder.build();
Retrofit retrofit =
new Retrofit.Builder().baseUrl(APIService.ENDPOINT).client(client).addConverterFactory(GsonConverterFactory.create()).addCallAdapterFactory(RxJavaCallAdapterFactory.create()).build();
return retrofit.create(APIService.class);
}
}
gradle file(使用する予定の場合はロギングインターセプターを追加する必要があります):
//----- Retrofit
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile "com.squareup.retrofit2:converter-gson:2.1.0"
compile "com.squareup.retrofit2:adapter-rxjava:2.1.0"
compile 'com.squareup.okhttp3:logging-interceptor:3.4.0'
リクエストとレスポンスをログに記録するためにはインターセプターが必要です。またヘッダーを設定するためにもインターセプターが必要です。
public OkHttpClient getHeader(final String authorizationValue ) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okClient = new OkHttpClient.Builder()
.addInterceptor(interceptor)
.addNetworkInterceptor(
new Interceptor() {
@Override
public Response intercept(Interceptor.Chain chain) throws IOException {
Request request = null;
if (authorizationValue != null) {
Log.d("--Authorization-- ", authorizationValue);
Request original = chain.request();
// Request customization: add request headers
Request.Builder requestBuilder = original.newBuilder()
.addHeader("Authorization", authorizationValue);
request = requestBuilder.build();
}
return chain.proceed(request);
}
})
.build();
return okClient;
}
今すぐあなたの後付けオブジェクトにクライアントでこのヘッダを追加してください
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.client(getHeader(authorizationValue))
.addConverterFactory(GsonConverterFactory.create())
.build();
私はJson Content Typeのために、Retrofit 1.9と2.0のための別の方法を見つけました。
@Headers({"Accept: application/json"})
@POST("user/classes")
Call<playlist> addToPlaylist(@Body PlaylistParm parm);
あなたはもっと多くのヘッダを追加することができます。
@Headers({
"Accept: application/json",
"User-Agent: Your-App-Name",
"Cache-Control: max-age=640000"
})
私の場合、addInterceptor()
は私のリクエストにHTTPヘッダを追加するようには動作しませんでした、私はaddNetworkInterceptor()
を使わなければなりませんでした。コードは以下のとおりです。
OkHttpClient.Builder httpClient = new OkHttpClient.Builder();
httpClient.addNetworkInterceptor(new AddHeaderInterceptor());
そしてインターセプターコード:
public class AddHeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
builder.addHeader("Authorization", "MyauthHeaderContent");
return chain.proceed(builder.build());
}
}
これともっと上の例 this Gist
Add HttpLoggingInterceptorにaddInterceptorメソッドを使用した場合、HttpLoggingInterceptorより後に適用された他のインターセプターによって追加されたものはログに記録されません。
たとえば、「HttpLoggingInterceptor」と「AuthInterceptor」という2つのインターセプターがあり、HttpLoggingInterceptorが最初に適用されている場合は、AuthInterceptorによって設定されたhttp-paramsまたはヘッダーを表示できません。
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addNetworkInterceptor(logging)
.addInterceptor(new AuthInterceptor());
AddNetworkInterceptorメソッドを使って解決しました。
このレトロフィットクライアントを使用する
class RetrofitClient2(context: Context) : OkHttpClient() {
private var mContext:Context = context
private var retrofit: Retrofit? = null
val client: Retrofit?
get() {
val logging = HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BODY)
val client = OkHttpClient.Builder()
.connectTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
.readTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
.writeTimeout(Constants.TIME_OUT, TimeUnit.SECONDS)
client.addInterceptor(logging)
client.interceptors().add(AddCookiesInterceptor(mContext))
val gson = GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ssZ").create()
if (retrofit == null) {
retrofit = Retrofit.Builder()
.baseUrl(Constants.URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.client(client.build())
.build()
}
return retrofit
}
}
すべてのリクエストとともにJWTを渡します。変数名を気にしないでください、少し混乱します。
class AddCookiesInterceptor(context: Context) : Interceptor {
val mContext: Context = context
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val builder = chain.request().newBuilder()
val preferences = CookieStore().getCookies(mContext)
if (preferences != null) {
for (cookie in preferences!!) {
builder.addHeader("Authorization", cookie)
}
}
return chain.proceed(builder.build())
}
}