一、Retrofit與OkHttp的關(guān)系
Retrofit是現(xiàn)在最為流行的網(wǎng)絡(luò)請求框架干毅,那么與OkHttp有什么關(guān)系呢宜猜?
Retrofit的底層是默認(rèn)是基于OkHttp,只不過Retrofit幫你封裝了請求前與請求后的過程溶锭。
那么既然是基于OkHttp宝恶,Okhttp是支持對請求頭Cookie的封裝。
二、結(jié)合OkHttp對請求頭的思路
在設(shè)置請求頭的時垫毙,使用header(name,value)方法來設(shè)置HTTP的頭的唯一值霹疫。可以通過OkHttp中Interceptor來攔截并重新設(shè)置請求頭综芥。隨后可以結(jié)合Retrofit的.client(OkHttpClient)進(jìn)行對請求頭的修改丽蝎,這是我們的思路。
三膀藐、處理
1.實現(xiàn)Interceptor處理請求頭屠阻,需要處理兩次:
- 首次請求cookie為空,需要從響應(yīng)報文中獲取额各,并保存到客戶端的首選項中国觉。
- 非首次請求時,從首選中中取出cookie并添加到請求頭中虾啦。
首次請求的處理:
/**
* @author : jc.lu
* @create : 17/07/07.
*/
public class ReceivedCookiesInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Response originalResponse = chain.proceed(chain.request());
if (!originalResponse.headers("Set-Cookie").isEmpty()) {
HashSet<String> cookies = new HashSet<>();
for (String header : originalResponse.headers("Set-Cookie")) {
cookies.add(header);
}
SharedPreferences.Editor config = MyApplication.getContext().getSharedPreferences("config", MyApplication.getContext().MODE_PRIVATE)
.edit();
config.putStringSet("cookie", cookies);
config.commit();
}
return originalResponse;
}
}
非首次請求:
/**
* @author : jc.lu
* @create : 17/07/07.
*/
public class AddCookiesInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request.Builder builder = chain.request().newBuilder();
HashSet<String> preferences = (HashSet) MyApplication.getContext().getSharedPreferences("config",
MyApplication.getContext().MODE_PRIVATE).getStringSet("cookie", null);
if (preferences != null) {
for (String cookie : preferences) {
builder.addHeader("Cookie", cookie);
Log.v("OkHttp", "Adding Header: " + cookie); // This is done so I know which headers are being added; this interceptor is used after the normal logging of OkHttp
}
}
return chain.proceed(builder.build());
}
}
2.將攔截器添加到OkHttpClient中
private static OkHttpClient client = new OkHttpClient.Builder()
.addNetworkInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
.addInterceptor(REWRITE_CACHE_CONTROL_INTERCEPTOR)
.addInterceptor(new AddCookiesInterceptor()) //這部分
.addInterceptor(new ReceivedCookiesInterceptor()) //這部分
.cache(cache)
.build();
3.創(chuàng)建retrofit并添加client
mRetrofit = new Retrofit.Builder()
.baseUrl(mBaseUrl)
.addConverterFactory(GsonConverterFactory.create(new GsonBuilder().create()))
.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
.client(client) //這部分
.build();
由此為止retrofit對cookie持久化的工作都完成了麻诀,看看效果。
首次請求:
非首次請求:
有圖有真相傲醉,可以看出cookie已經(jīng)被添加到每次請求的請求頭上去了蝇闭。
總結(jié)
使用這種方法可以有效解決retrofit請求頭對cookie的封裝。注意Interceptor攔截器不止是可以添加cookie硬毕,可以自定義添加任何屬性呻引,當(dāng)然這是取決于實際需要和后臺與客戶端的如何處理了。
如果不想使用這種方法添加cookie可以使用這個第三方庫吐咳,簡單到爆炸……
https://github.com/franmontiel/PersistentCookieJar