使用 Retrofit 2 向所有请求添加 header
Adding header to all request with Retrofit 2
Headers that need to be added to every request can be specified using an OkHttp interceptor.
使用以前的版本可以轻松完成,here's相关QA。
但是使用改造 2,我找不到类似 setRequestInterceptor
或 setInterceptor
的方法可以应用于 Retrofit.Builder
object。
另外 OkHttp anymore. Retrofit's doc refers us to Interceptor 中似乎没有 RequestInterceptor
,我不太明白如何将其用于此目的。
我该怎么做?
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 headers 添加到我的请求中,我不得不使用 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
上的更多示例
为了记录您的请求和响应,您需要一个拦截器,并且为了设置 header 您需要一个拦截器,这是使用改造 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;
}
现在在您的改造中 object 在客户端中添加此 header
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.client(getHeader(authorizationValue))
.addConverterFactory(GsonConverterFactory.create())
.build();
如果使用 addInterceptor 方法添加 HttpLoggingInterceptor,它将不会记录由晚于 HttpLoggingInterceptor 应用的其他拦截器添加的内容。
例如:如果你有两个拦截器 "HttpLoggingInterceptor" 和 "AuthInterceptor",并且 HttpLoggingInterceptor 首先应用,那么你
无法查看 AuthInterceptor 设置的 http-params 或 headers。
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addNetworkInterceptor(logging)
.addInterceptor(new AuthInterceptor());
我通过使用 addNetworkInterceptor 方法解决了它。
为 Retrofit 1.9 和 2.0 尝试这种类型 header。对于 Json 内容类型。
@Headers({"Accept: application/json"})
@POST("user/classes")
Call<playlist> addToPlaylist(@Body PlaylistParm parm);
您可以添加更多 header,即
@Headers({
"Accept: application/json",
"User-Agent: Your-App-Name",
"Cache-Control: max-age=640000"
})
动态添加到 headers:
@POST("user/classes")
Call<ResponseModel> addToPlaylist(@Header("Content-Type") String content_type, @Body RequestModel req);
叫你方法即
mAPI.addToPlayList("application/json", playListParam);
或
想要每次都通过,然后使用 http 拦截器创建 HttpClient object:
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());
}
});
然后添加改造object
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())}
RetrofitHelper 库用 kotlin 编写,可以让您使用几行代码进行 API 调用。
像这样在您的应用程序 class 中添加 headers:
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)
有关详细信息,请参阅 documentation
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()
}
Headers that need to be added to every request can be specified using an OkHttp interceptor.
使用以前的版本可以轻松完成,here's相关QA。
但是使用改造 2,我找不到类似 setRequestInterceptor
或 setInterceptor
的方法可以应用于 Retrofit.Builder
object。
另外 OkHttp anymore. Retrofit's doc refers us to Interceptor 中似乎没有 RequestInterceptor
,我不太明白如何将其用于此目的。
我该怎么做?
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 headers 添加到我的请求中,我不得不使用 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
上的更多示例为了记录您的请求和响应,您需要一个拦截器,并且为了设置 header 您需要一个拦截器,这是使用改造 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;
}
现在在您的改造中 object 在客户端中添加此 header
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(url)
.client(getHeader(authorizationValue))
.addConverterFactory(GsonConverterFactory.create())
.build();
如果使用 addInterceptor 方法添加 HttpLoggingInterceptor,它将不会记录由晚于 HttpLoggingInterceptor 应用的其他拦截器添加的内容。
例如:如果你有两个拦截器 "HttpLoggingInterceptor" 和 "AuthInterceptor",并且 HttpLoggingInterceptor 首先应用,那么你 无法查看 AuthInterceptor 设置的 http-params 或 headers。
OkHttpClient.Builder builder = new OkHttpClient.Builder()
.addNetworkInterceptor(logging)
.addInterceptor(new AuthInterceptor());
我通过使用 addNetworkInterceptor 方法解决了它。
为 Retrofit 1.9 和 2.0 尝试这种类型 header。对于 Json 内容类型。
@Headers({"Accept: application/json"})
@POST("user/classes")
Call<playlist> addToPlaylist(@Body PlaylistParm parm);
您可以添加更多 header,即
@Headers({
"Accept: application/json",
"User-Agent: Your-App-Name",
"Cache-Control: max-age=640000"
})
动态添加到 headers:
@POST("user/classes")
Call<ResponseModel> addToPlaylist(@Header("Content-Type") String content_type, @Body RequestModel req);
叫你方法即
mAPI.addToPlayList("application/json", playListParam);
或
想要每次都通过,然后使用 http 拦截器创建 HttpClient object:
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());
}
});
然后添加改造object
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())}
RetrofitHelper 库用 kotlin 编写,可以让您使用几行代码进行 API 调用。
像这样在您的应用程序 class 中添加 headers:
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)
有关详细信息,请参阅 documentation
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()
}