retrofit的請(qǐng)求頭添加從添加方式來(lái)說(shuō)可以分為三種情況,靜態(tài)、動(dòng)態(tài)和全局。
靜態(tài)添加
靜態(tài)添加是用于在定義請(qǐng)求時(shí)就明確知道需要添加那些請(qǐng)求頭
比如下面的接口需要添加一個(gè)apikey的請(qǐng)求頭及一個(gè)cityname的url請(qǐng)求參數(shù)
public interface WeatherService {
@Headers("apikey:b86c2269fe6588bbe3b41924bb2f2da2")
@GET
Call<WeatherWrapper> weather(@Url String url, @Query("cityname") String cityName);
}
如果有多個(gè)請(qǐng)求頭也可以定義成鍵值對(duì)的樣式
@Headers({
"key1:value1",
"key2:value2"
})
上面的兩種寫(xiě)法,適用于鍵和值都明確的情況。在值還不確定的時(shí)候我們可以把請(qǐng)求頭像請(qǐng)求參數(shù)一樣寫(xiě)到括號(hào)里,加上@Header注解就可以。算是一種狹義上的偽動(dòng)態(tài)寫(xiě)法
@GET
Call<WeatherWrapper> weather(@Header("apikey") String apikey, @Url String url, @Query("cityname") String cityName);
動(dòng)態(tài)添加
動(dòng)態(tài)添加用于請(qǐng)求頭是變化的,鍵和值都需要根據(jù)具體的情況才能確定,這時(shí)我們會(huì)需要@HeaderMap ,用一個(gè)map來(lái)提供請(qǐng)求頭,具體寫(xiě)法如下
@GET
Call<WeatherWrapper> weather(@HeaderMap Map<String, String> headers, @Url String url, @Query("cityname") String cityName);
全局添加
全局添加用于所有請(qǐng)求都需要帶上的請(qǐng)求頭,如手機(jī)型號(hào)、APP版本等等,這種顯然不適合在每個(gè)請(qǐng)求上去添加@Header注解。全局添加需要用到攔截器
okHttpClientBuilder.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
Request.Builder requestBuilder = original.newBuilder()
.header("token", "xxx")
.header("token", "yyy");
Request request = requestBuilder.build();
return chain.proceed(request);
}
});
需要注意的是這里的.header會(huì)導(dǎo)致重寫(xiě),如果之前在url里定義了一個(gè)相同鍵的請(qǐng)求頭,那么在這里會(huì)被從新賦值。如果不希望被覆蓋,使用.addHeader()方法替換就可以了
延伸
既然用到了攔截器,添加公共請(qǐng)求頭。那能不能一次性給所有請(qǐng)求頭添加一個(gè)一樣的參數(shù)?當(dāng)然可以
如下:給每個(gè)請(qǐng)求添加一個(gè)access_token參數(shù)
okHttpClientBuilder.addInterceptor(new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
HttpUrl originalHttpUrl = originalRequest.url();
HttpUrl url = originalHttpUrl.newBuilder()
.addQueryParameter("access_token", AccessTokenKeeper.readAccessToken(MyApplication.getInstance()).getToken())
.build();
Request request = originalRequest.newBuilder()
.url(url)
.method(originalRequest.method(), originalRequest.body())
.build();
return chain.proceed(request);
}
});