Android 使用Okhttp/Retrofit持久化cookie的简便方式

首先cookie是什么就很少说了,仍是不知道的话推荐看看这篇文章 
Cookie/Session机制详解 
深刻解析Cookie技术html

为何要持久化cookie也很少说了,你能看到这篇文章表明你有这个需求。git

cookie简单来讲就是服务器在客户端中保存的键值对,好比说早期的购物车,保持登录状态都是使用的cookie。 
可是cookie的功能是依赖于浏览器的,大多数浏览器都有管理cookie的功能。固然,你也能经过设置禁止掉这项功能,毕竟cookie是很容易泄露用户隐私的github

上面也说了cookie功能依赖于客户端,很明显,在开发app的时候咱们也要手动管理cookie了。web

 

持久化cookie以前,咱们最好了解一下cookie是怎么传输的,看完以后我想你就能使用很简单的方式去保持cookie了。

1. cookie是怎么传输的

Cookie使用HTTPHeader传递数据。 
Cookie机制定义了两种报头:Set-Cookie报头和Cookie报头。segmentfault

Set-Cookie报头包含于Web服务器的响应头(ResponseHeader)中 
Cookie报头包含在浏览器客户端请求头(ReguestHeader)中浏览器

Cookie的运行过程如图所示,具体分析以下 
这里写图片描述服务器

2. 简单粗暴持久化cookie的方式

方法来源于这http://tsuharesu.com/handling-cookies-with-okhttp/cookie

看了cookie的传输原理以后咱们就能够用一个简单的方式持久化cookie了,那就是经过okhttp的intercept方式手动往header中写入cookie或者获取cookie。app

/**
 * This interceptor put all the Cookies in Preferences in the Request.
 * Your implementation on how to get the Preferences MAY VARY.
 * <p>
 * Created by tsuharesu on 4/1/15.
 */
public class AddCookiesInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request.Builder builder = chain.request().newBuilder();
        HashSet<String> preferences = (HashSet) Preferences.getDefaultPreferences().getStringSet(Preferences.PREF_COOKIES, new HashSet<>());
        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());
    }
}
/**
 * This Interceptor add all received Cookies to the app DefaultPreferences.
 * Your implementation on how to save the Cookies on the Preferences MAY VARY.
 * <p>
 * Created by tsuharesu on 4/1/15.
 */
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);
            }

            Preferences.getDefaultPreferences().edit()
                    .putStringSet(Preferences.PREF_COOKIES, cookies)
                    .apply();
        }

        return originalResponse;
    }
}
/**
 * Somewhere you create a new OkHttpClient and use it on all your requests.
 */
OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.interceptors().add(new AddCookiesInterceptor());
okHttpClient.interceptors().add(new ReceivedCookiesInterceptor());

简单的cookie持久化能够用这种方式,建立一个单例的client,全局都使用这个client请求接口。固然你也能够每次new一个client从新设置intercept……ide

还要记住的是,cookie是针对于域名存储的。好比:www.baidu.com和image.baidu.com存储的cookies都是不同的…… 
若是你的app真的须要同时访问两个域名的接口,而且两个都须要持久化cookie,那么记得作判断(好比用域名做为key存储cookie到sharepreference中)。不然两个域名的cookie会互相覆盖掉……

3. 本体在这里,okhttp 3.0 cookie的管理

相关原理能够看看这篇文章 OkHttp3之Cookies管理及持久化

而后,持久化管理cookie能够直接使用这个开源库,简单到爆炸…… 
https://github.com/franmontiel/PersistentCookieJar

固然,你也可使用鸿洋大神的okhttputils,该库也提供了cookie的持久化管理工具。用起来和上面同样方便

相关文章
相关标签/搜索