Adding header to all request with Retrofit 2

Retrofit 2's documentation says:

Headers that need to be added to every request can be specified using an OkHttp interceptor.

It can be done easily using the previous version, here's the related QA.

But using retrofit 2, I couldn't find something like setRequestInterceptor or setInterceptor method that can be applied to Retrofit.Builder object.

Also it seems that there's no RequestInterceptor in OkHttp anymore. Retrofit's doc refers us to Interceptor that I didn't quite understand how to use it for this purpose.

How can I do this?

153164 次浏览
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();

最新的翻新版本: > 2.1.0。

Lambda 版本:

  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 文件(如果您计划使用它,则需要添加日志拦截器) :

  //----- 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'

在我的情况下,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());
}
}

这个和更多的例子在 这个要点

为了记录您的请求和响应,您需要一个拦截器,并且为了设置头部,您需要一个拦截器,下面是一次添加这两个拦截器的解决方案,使用修改2.1

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

如果使用 addInterceptor 方法添加 HttpLoggingInterceptor,那么它不会记录其他拦截器添加的比 HttpLoggingInterceptor 晚应用的内容。

例如: 如果有两个拦截器“ HttpLoggingInterceptor”和“ AuthInterceptor”,并且首先应用了 HttpLoggingInterceptor,则 无法查看由 AuthInterceptor 设置的 http-params 或头文件。

OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addNetworkInterceptor(logging)
.addInterceptor(new AuthInterceptor());

我解决了它,通过使用 addNetworkInterceptor 方法。

请尝试使用这个类型头文件,以便进行修改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"
})

动态添加到标题:

@POST("user/classes")
Call<ResponseModel> addToPlaylist(@Header("Content-Type") String content_type, @Body RequestModel req);

称你为方法即

mAPI.addToPlayList("application/json", playListParam);

或者

希望每次都传递,然后使用 http 拦截器创建 HttpClient 对象:

OkHttpClient httpClient = new OkHttpClient();
httpClient.networkInterceptors().add(new Interceptor() {
@Override
public com.squareup.okhttp.Response intercept(Chain chain) throws IOException {
Request.Builder requestBuilder = chain.request().newBuilder();
requestBuilder.header("Content-Type", "application/json");
return chain.proceed(requestBuilder.build());
}
});

然后添加到改造对象

Retrofit retrofit = new Retrofit.Builder().baseUrl(BASE_URL).client(httpClient).build();

更新 如果您使用 Kotlin 删除 { }否则它将不起作用

使用此改造客户端

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

在 Kotlin 中增加拦截器看起来是这样的:

.addInterceptor{ it.proceed(it.request().newBuilder().addHeader("Cache-Control", "no-store").build())}

使用 kotlin 编写的 RevifitHelper 库,将允许您使用几行代码进行 API 调用。

在应用程序类中添加头部,如下所示:

class Application : Application() {


override fun onCreate() {
super.onCreate()


retrofitClient = RetrofitClient.instance
//api url
.setBaseUrl("https://reqres.in/")
//you can set multiple urls
//                .setUrl("example","http://ngrok.io/api/")
//set timeouts
.setConnectionTimeout(4)
.setReadingTimeout(15)
//enable cache
.enableCaching(this)
//add Headers
.addHeader("Content-Type", "application/json")
.addHeader("client", "android")
.addHeader("language", Locale.getDefault().language)
.addHeader("os", android.os.Build.VERSION.RELEASE)
}


companion object {
lateinit var retrofitClient: RetrofitClient


}
}

然后打电话:

retrofitClient.Get<GetResponseModel>()
//set path
.setPath("api/users/2")
//set url params Key-Value or HashMap
.setUrlParams("KEY","Value")
// you can add header here
.addHeaders("key","value")
.setResponseHandler(GetResponseModel::class.java,
object : ResponseHandler<GetResponseModel>() {
override fun onSuccess(response: Response<GetResponseModel>) {
super.onSuccess(response)
//handle response
}
}).run(this)

有关详细信息,请参阅 文件

Kotlin 的版本是

fun getHeaderInterceptor():Interceptor{
return object : Interceptor {
@Throws(IOException::class)
override fun intercept(chain: Interceptor.Chain): Response {
val request =
chain.request().newBuilder()
.header(Headers.KEY_AUTHORIZATION, "Bearer.....")
.build()
return chain.proceed(request)
}
}
}




private fun createOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.apply {
if(BuildConfig.DEBUG){
this.addInterceptor(HttpLoggingInterceptor().setLevel(HttpLoggingInterceptor.Level.BASIC))
}
}
.addInterceptor(getHeaderInterceptor())
.build()
}