retrofit怎么针对不同的url统一添加header?

目前我是使用retrofit来作为我的网络请求框架,对某些请求还需要加headers。我在官网查到有@Header标签来指定header参数,但是这样写的话太繁琐,如果service中方法比较多的话,不是要写死了。又在网上又查了下,可以使用自定义的OkHttpClient来实现,然后使用:

Retrofit retrofit = new Retrofit.Builder()  
            .baseUrl(SERVER_URL)  
            .client(genericClient())  
            .build();

但是这种做法的话,就会把所有使用这个retrofit的url都加上了header,但是部分url是不需要的,比如我只是想在需要授权的url调用上都加上header参数(header里面加token)。找了半天网上没有相关的文章,所以请SF的朋友们回答下,谢谢!

阅读 10.1k
4 个回答

我是这么写的

OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.addInterceptor(new Interceptor() {
    @Override
    public Response intercept(Chain chain) throws IOException, java.io.IOException {
        Request request = chain.request().newBuilder()
                .addHeader("Source", "android")
                .addHeader("Accept", "application/json,text/javascript,*/*")
                .build();
        return chain.proceed(request);
    }
});
OkHttpClient client = builder.build();

retrofit = new Retrofit.Builder()
        .baseUrl(BASE_TRC_URL)
        .client(client)
        .addConverterFactory(GsonConverterFactory.create(getGson()))
        .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
        .build();

但是这样不能统一加token

使用okhttp的interceptor就可以

我也遇到了这样的问题,我写了一个拦截器

public final class TokenInterceptor extends Application implements Interceptor{
    private static final String TAG="TokenInterceptor";
    private static final String USER_TOKEN = "Authorization";
    private String token;
    public TokenInterceptor(String token) {
        this.token = token;
        Log.d(TAG,"tk1:"+token);
    }
    @Override
    public Response intercept(Chain chain) throws IOException {
        final Request originalRequest = chain.request();
        Log.d(TAG,"url=============="+originalRequest.url()+"\ttoken:"+token);
        Log.d(TAG,"header:"+originalRequest.header("Authorization") );
        if(token.isEmpty() || token == null || originalRequest.header("Authorization") != null){
            Log.d(TAG,"if true");
            return chain.proceed(originalRequest);
        }
        Request request = originalRequest.newBuilder()
                .header(USER_TOKEN,"Token "+token)
                .build();
        return chain.proceed(request);
    }
}

然后用okhttp client调用

OkHttpClient.Builder builder = new OkHttpClient.Builder();

builder.addNetworkInterceptor(new TokenInterceptor(tk));

我终于明白了,其实客户端不要区分的那么细,从本地配置文件取token,有就传,没有就不传,后台做好控制哪些url需要,哪些url不需要就可以。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题