本质:同步cookie的本质就是Http框架的cookie与webview的cookie不同,无法区别为同一个用户,使用统一持久化过的cookie有助于后台区别用户。
业务场景:做一个临时打卡系统,使用http框架请求后台接口,获取打卡页面url,使用webview加载url实现打卡。打卡失败就关闭网页,返回上个页面。
问题:看似很容易的场景,发现一个问题就是每次webview打开的url后,后台的jsessionid都是不同的(最开始是没有的),无法区分同一个用户。【请求cookie中的jsessionid是变化的】
解决方案:后台没有jsessionid是因为接口没有调用session相关的接口,没调用就没有jsessionid返回。说说安卓端,http框架请求时获取的jsessionid与webview打开页面的jsessionid是不同的,服务端无法判断同一个用户,如何不变化就要我们自己去同步cookie。
每次打开url前先同步一下cookie,这个cookie就使用http框架的持久化的过的cookie,这样每次load url都是一样的jsessionid啦。
所以在访问需要登录信息(jsessionid)的页面时必须同步cookie。如果遇到ajax没有同步成功的情况,可以考虑url传参。对于第一次请求重要接口没有jsessionid这种问题,就搞一次其他请求先于这个接口,把重要的接口放在后面就肯定有jsessionid啦。
/**
* 将cookie同步到WebView
*
* @param url WebView要加载的url
* @param cookie 要同步的cookie
* @return true 同步cookie成功,false同步cookie失败
* @Author JPH
*/
public void syncCookie(String url, List<Cookie> cookies) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
CookieSyncManager.createInstance(this);
}
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.removeAllCookie();
StringBuffer sb = new StringBuffer();
for (Cookie cookie : cookies) {
String cookieName = cookie.getName();
String cookieValue = cookie.getValue();
if (!TextUtils.isEmpty(cookieName)
&& !TextUtils.isEmpty(cookieValue)) {
sb.append(cookieName + "=");
sb.append(cookieValue + ";");
}
}
String[] cookie = sb.toString().split(";");
for (int i = 0; i < cookie.length; i++) {
Log.i(TAG,"cookie:"+cookie[i]);
cookieManager.setCookie(url, cookie[i]);// cookies是在HttpClient中获得的cookie
}
CookieSyncManager.getInstance().sync();
}
----------------------------------------------------------------------------------------------------------------------------------------
什么是Jsessionid????
1)第一次访问服务器的时候,会在响应头里面看到Set-Cookie信息(只有在首次访问服务器的时候才会在响应头中出现该信息)
。
上面的图JSESSIONID=ghco9xdnaco31gmafukxchph;Path=/acr,
浏览器会根据响应头的set-cookie信息设置浏览器的cookie并保存之
注意此cookie由于没有设置cookie有效日期,所以在关闭浏览器的情况下会丢失掉这个cookie。
2)当再次请求的时候(非首次请求),浏览器会在请求头里将cookie发送给服务器(每次请求都是这样)
(JSESSIONID=ghco9xdnaco31gmafukxchph)
不难发现这个的jsessionid和上面的jsessionid是一样的
3)为什么除了首次请求之外每次请求都会发送这个cookie呢(在这里确切地说是发送这个jsessionid)?
事实上当用户访问服务器的时候会为每一个用户开启一个session,浏览器是怎么判断这个session到底是属于哪个用户呢?jsessionid的作用就体现出来了:jsessionid就是用来判断当前用户对应于哪个session。换句话说服务器识别session的方法是通过jsessionid来告诉服务器该客户端的session在内存的什么地方。
事实上jsessionid ==request.getSession().getId()
4)总结,jsessionid的工作流程可以简单用下面的图表示: