需求:
没有登陆时接口照常使用,登陆后请求数据需要在请求头里带token过去。
问题:
这个header的声明方式有几种,常见的是在创建单例接口类时就给声明了header,而这个单例在第一次请求数据的时候就创建了,那时候如果没有登陆,那登陆后依然是用的同一个header,就带不过去这个token。另一种就是在声明接口的时候添加@Header()注解,但是这样的话需要每个接口上面都写这个,就比较麻烦。
解决思路:
用OKHttp做请求拦截,如果没有登陆(SharedPreferences中没有获取到token)就用原来的请求,如果登陆了,就添加一个请求头,请求头里面添加一个key-value给token。
具体代码实现:
1、自定义拦截器:
//在请求头里添加token的拦截器处理
public class TokenHeaderInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
String token = SpUtils.getToken(); //SpUtils是SharedPreferences的工具类,自行实现
if (token.isEmpty()) {
Request originalRequest = chain.request();
return chain.proceed(originalRequest);
}else {
Request originalRequest = chain.request();
//key的话以后台给的为准,我这边是叫token
Request updateRequest = originalRequest.newBuilder().header("token", token).build();
return chain.proceed(updateRequest);
}
}
}
2、给okhttp添加拦截器:
private OkHttpClient.Builder getClient(){
OkHttpClient.Builder httpClientBuilder = new OkHttpClient.Builder();
httpClientBuilder.connectTimeout(15, TimeUnit.SECONDS);
httpClientBuilder.addNetworkInterceptor(new TokenHeaderInterceptor());
return httpClientBuilder;
}
3、Retrofit创建的时候添加这个OkHttpClient:
Retrofit build = new Retrofit.Builder()
.baseUrl(BaseConstant.API_URL)
.client(getClient().build())
.addConverterFactory(GsonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();