Android端实现Cookie机制

简介

Sessions是服务端验证客户端身份的一种机制。而Cookies是客户端存储的一种身份凭证,是由服务端在回应的消息头中通过Set-Cookie字段“种”在客户端。以后每次客户端在向服务端请求时都会在消息头中带上Cookie字段。服务端就会根据这个Cookie的头来判断此次请求是从哪个用户发过来的,是否是一次有效请求等。

请求www.baidu.com举例

首次打开浏览器请求http://www.baidu.com,得到的response消息头
Android端实现Cookie机制_第1张图片
可以看到里面包含了几个“种”Cookie。此时我们再查看浏览器的Cookie,可以看到这些Cookie信息被“种”下了。
本地cookie信息
此时再发送一条请求,可以看到请求的消息头如下:
请求消息头Cookie信息

客户端实现

Android自身所带的HttpUrlConnection方法是默认不开启Cookie存储的。不过我们可以用java提供的几个类来在Android中实现:
可以先在所有请求之前声明

CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));

开启此开关后,每次请求的Set-Cookie信息都会被CookieManager处理。CookieManager又会使用第一个参数传入的CookieStore来处理Cookie的存储问题,因为此处传入了null,系统会默认调用一个基于CookieStore实现的CookieStoreImpl类来处理Cookie的存储,这个类的只有基于内存的存储,当进程被杀死后,下次再进入应用,保存的Cookie信息就会丢失。所以我们需要基于CookieStore这个接口实现一个具有内存和本地双存储机制的Cookie存储类。

可以参考:Fran Montiel实现的PersistentCookieStore 类:
https://gist.github.com/franmontiel/ed12a2295566b7076161

当解决了Cookie的存储后,我们就需要考虑以后我们的每次请求需要在请求的消息头中加入Cookie字段。以上用CookieStore存储下来的Cookie信息都会被保存成HttpCookie形式的信息。我们可以上面的百度例子中看到Cookie的组成样式,所以我们可以提取CookieStore中的信息并组合。

StringBuilder cookieBuilder = new StringBuilder();
String divider = "";
for (HttpCookie cookie : getCookies()) {
    cookieBuilder.append(divider);
    divider = ";";
    cookieBuilder.append(cookie.getName());
    cookieBuilder.append("=");
    cookieBuilder.append(cookie.getValue());
}
cookieString = cookieBuilder.toString();

然后把这个cookieString在以后的请求中加入到头中,如果你用HttpUrlConnection,你就可以

setRequestProperty("Cookie",cookieString);  

OK,大功告成。

以下是我在Github上开源的一个基于Volley实现的网络层框架,也包括Cookie机制的Http请求,欢迎大家fork:
https://github.com/CPPAlien/DaVinci

你可能感兴趣的:(Android那些事儿)