retrofit的请求头添加从添加方式来说可以分为三种情况,静态、动态和全局。
静态添加
静态添加是用于在定义请求时就明确知道需要添加那些请求头
比如下面的接口需要添加一个apikey的请求头及一个cityname的url请求参数
public interface WeatherService { @Headers("apikey:b86c2269fe6588bbe3b41924bb2f2da2") @GET Call<WeatherWrapper> weather(@Url String url, @Query("cityname") String cityName); }
如果有多个请求头也可以定义成键值对的样式
@Headers({ "key1:value1", "key2:value2" })
上面的两种写法,适用于键和值都明确的情况。在值还不确定的时候我们可以把请求头像请求参数一样写到括号里,加上@Header注解就可以。算是一种狭义上的伪动态写法
@GET Call<WeatherWrapper> weather(@Header("apikey") String apikey, @Url String url, @Query("cityname") String cityName);
动态添加
动态添加用于请求头是变化的,键和值都需要根据具体的情况才能确定,这时我们会需要@HeaderMap ,用一个map来提供请求头,具体写法如下
@GET Call<WeatherWrapper> weather(@HeaderMap Map<String, String> headers, @Url String url, @Query("cityname") String cityName);
全局添加
全局添加用于所有请求都需要带上的请求头,如手机型号、APP版本等等,这种显然不适合在每个请求上去添加@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
会导致重写,如果之前在url里定义了一个相同键的请求头,那么在这里会被从新赋值。如果不希望被覆盖,使用.addHeader()
方法替换就可以了
延伸
既然用到了拦截器,添加公共请求头。那能不能一次性给所有请求头添加一个一样的参数?当然可以
如下:给每个请求添加一个access_token
参数
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); } });
1+