android中有时候需要保存由服务器返回的cookie,那么如何存取呐?
这需要我们自定义两个拦截器来实现
SaveCookiesInterceptor和AddCookiesInterceptor
首先定义响应拦截器,该拦截器实现从response获取set-cookie字段的值,并将其保存在本地。
代码如下:
public class SaveCookiesInterceptor implements Interceptor {
private static final String COOKIE_PREF = "cookies_prefs";
private Context mContext;
public SaveCookiesInterceptor(Context context) {
mContext = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
//set-cookie可能为多个
if (!response.headers("set-cookie").isEmpty()) {
List<String> cookies = response.headers("set-cookie");
String cookie = encodeCookie(cookies);
saveCookie(request.url().toString(),"gfan.com",cookie);
}
return response;
}
//整合cookie为唯一字符串
private String encodeCookie(List<String> cookies) {
StringBuilder sb = new StringBuilder();
Set<String> set=new HashSet<>();
for (String cookie : cookies) {
String[] arr = cookie.split(";");
for (String s : arr) {
if(set.contains(s))continue;
set.add(s);
}
}
Iterator<String> ite = set.iterator();
while (ite.hasNext()) {
String cookie = ite.next();
sb.append(cookie).append(";");
}
int last = sb.lastIndexOf(";");
if (sb.length() - 1 == last) {
sb.deleteCharAt(last);
}
return sb.toString();
}
//保存cookie到本地,这里我们分别为该url和host设置相同的cookie,其中host可选
//这样能使得该cookie的应用范围更广
private void saveCookie(String url,String domain,String cookies) {
SharedPreferences sp = mContext.getSharedPreferences(COOKIE_PREF, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
if(url.contains("index.php?m=member&c=gfan_index&a=login")){
if (!TextUtils.isEmpty(domain)) {
editor.putString(domain, cookies);
}
editor.apply();
}
}
}
其次定义请求拦截器,如果该请求存在cookie,则为其添加到Header的Cookie中,代码如下:
代码如下:
public class AddCookiesInterceptor implements Interceptor {
private static final String COOKIE_PREF = "cookies_prefs";
private Context mContext;
public AddCookiesInterceptor(Context context) {
mContext = context;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Request.Builder builder = request.newBuilder();
String cookie = getCookie("", "gfan.com");
if (!TextUtils.isEmpty(cookie)) {
builder.removeHeader("cookie");
builder.addHeader("cookie", cookie);
}
return chain.proceed(builder.build());
}
private String getCookie(String url, String domain) {
SharedPreferences sp = mContext.getSharedPreferences(COOKIE_PREF, Context.MODE_PRIVATE);
if (!TextUtils.isEmpty(domain)&&sp.contains(domain) && !TextUtils.isEmpty(sp.getString(domain, ""))) {
return sp.getString(domain, "");
}
return null;
}
}
最后在设置一下这两个拦截器即可
代码如下:
OkHttpClient.Builder builder = new OkHttpClient.Builder();
builder.connectTimeout(TIME_OUT, TimeUnit.SECONDS);
builder.addInterceptor(new AddCookiesInterceptor(MYApplication.appContext));
builder.addInterceptor(new SaveCookiesInterceptor(MYApplication.appContext));
```
参考文章:
[急速开发系列——Retrofit实现持久化Cookie的三种方案](http://www.2cto.com/kf/201609/548735.html)