Android volley和webview同步cookies
2015-06-11 16:56
375 查看
Android volley和webview同步cookies
移动开发免不了要与服务器通信,说白了客户端也就是个升级版的浏览器罢了;其实也不算升级,有些地方升级有些地方降级了,哈哈哈;好吧说正事,通常我们与服务器通信为了数据的安全都会有验证,在浏览器中我们登录之后就可以访问任何一个页面;浏览器会保存用户与服务器的一个会话,那么要保证是同一个链接,浏览器每次请求都会携带这个会话(也就是链接)的标识seeeionid;so 我们就可以用同一链接与服务器通信,这样做的好处是减少并发量,避免了服务器的开销;好吧,那么问题来了我们做客户端在与服务器交互通常不是通过浏览器,而是通过HttpClient或是HttpURLConnection这两种方式;那么就要求我们自己来管理session(其实开发过web的同学很容易理解);
Cookie格式
上图我是请求某服务器在Chrome浏览器中查看请求的头携带的数据,如上图所示,浏览器会发送给服务器一堆数据,当然这些都是我们不关心的(有兴趣的可以去看看HTTP协议);
我们只关心浏览器发送了什么玩意导致可以复用会话,而不用再起连接;好吧那就是Cookie;
**Cookie:**Cookie,有时也用其复数形式Cookies,指某些网站为了辨别用户身份、进行session跟踪而储存在用户本地终端上的数据(通常经过加密)。 —— [ 百度百科 ]
知道了cookie的格式那么问题就好办了,我们只需要以Cookie为key,后面的一长串为value放到http请求头中发送给服务器就可以了;
获取Cookie并发送到服务器
获取Cookie:用户在第一次登录的时候,服务器响应头会返回Cookie,以Set-Cookie为key,后面的内容就是我们接下来请求服务器要发送的内容;值得注意的是Set-Cookie的存在依赖于服务器,不是每次都会返回Set-Cookie;当我们请求携带Cookie的时候服务器响应也许就不会返回Set-Cookie了;
HttpClient获取Cookie并发送:
参考链接:http://blog.csdn.net/yang_734664103/article/details/22025907
说白了总结就如下:
[code]DefaultHttpClient client = new DefaultHttpClient(); CookieStore store = client.getCookieStore(); List<Cookie> list = store.getCookies();
他可以获取到Cookie中精确的内容,我们要发送的是所有的值,而不只是=号后面的;所以把List列表拼接成字符串一起发送到服务端为好;
HttpURLConnection获取Cookie并发送:
参考链接:http://blog.csdn.net/chindroid/article/details/7556363
发现有时候自己也很懒啊,不自己写出来还得参考别人的文章,哈哈:);
Volley方式获取Cookie并发送:
说实在的如今用原生的Http访问网络的方式以及很少了,Android开源的网络框架层出不穷,而且都十分方便;或许有些框架也已经自带了Cookie的功能,下面我们就以Volley为例自定义Post请求,并获取Cookie;
[code]public class StringPostRequest extends StringRequest { private static final String TAG = "StringPostRequest"; private Map<String, String> mMap; private Map<String, String> mHeaders = new HashMap<String, String>(); public StringPostRequest(String url, Listener<String> listener, ErrorListener errorListener, Map<String, String> map) { super(Request.Method.POST, url, listener, errorListener); this.mMap = map; } @Override protected Response<String> parseNetworkResponse(NetworkResponse response) { try { Map<String, String> responseHeaders = response.headers; String rawCookies = responseHeaders.get("Set-Cookie"); String dataString = new String(response.data, "UTF-8"); Log.d(TAG, "Cookies:" + rawCookies); // 获取Cookie值并保存在SharedPreferences中 if (rawCookies != null) { CustomUtil.save(CustomUtil.COOKIE, rawCookies); } return Response.success(dataString, HttpHeaderParser.parseCacheHeaders(response)); } catch (UnsupportedEncodingException e) { return Response.error(new ParseError(e)); } } @Override protected Map<String, String> getParams() throws AuthFailureError { return mMap; } @Override public Map<String, String> getHeaders() throws AuthFailureError { Log.i(TAG, "保存在SharedPreferences中:" + mHeaders.get("Cookie")); return mHeaders; } /** * 设置Cookie * * @param cookie */ public void setSendCookie(String cookie) { mHeaders.put("Cookie", cookie); } }
该代码中就两处parseNetworkResponse中我们第一次登录获取Cookie,在请求其他链接的时候我们在setSendCookie中设置Cookie这样我们也是可以同一个会话中操作了;
App与WebView共存同步Cookie
如今的app已经是以Native为主打,webView辅助显示页面为主要的模式了;那么问题又来了,Native的Cookie如何同步到webview,或者webview的Cookie同步到Native;给WebView设置Cookie:
[code]CookieManager mCookieManager; ... public void synCookies() { CookieSyncManager.createInstance(this); mCookieManager = CookieManager.getInstance(); mCookieManager.setAcceptCookie(true); // 每次移除会有Cookie不一致问题,注释该地方 //mCookieManager.removeSessionCookie();// 移除 // Cookie是通过我们Volley活着HttpClient获取的 mCookieManager.setCookie(url, CustomUtil.get(CustomUtil.COOKIE)); CookieSyncManager.getInstance().sync(); }
该方法什么时候调用?在webview.loadUrl()调用之前设置Cookie,这样我们用Native登录的会话也可以在webview中复用了;
获取WebView中的Cookie:
基于上面的方式我们获取CookieManager的实例并在webviewonPageFinished方法中获取Cookie;
[code]mWebView.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // TODO Auto-generated method stub return false; } @Override public void onPageFinished(WebView view, String url) { super.onPageFinished(view, url); // 获取Cookie String cookie = mCookieManager.getCookie(url); Log.i("WebActivity", "cookie:" + cookie); } });
同样获取Cookie也可以设置给用Volley或者HttpClient访问服务器的方式了;
总结
Cookie的存在与否取决于服务端的设置,我们客户端也只是接收或者保存服务器的数据;有些人可能会遇到用了以上方式还是不行,那就得与你的服务端开发人员多交流了,他们的设置可能会对客户端或者浏览器产生一定的影响;也希望大家多尝试,原理其实很简单,剩下的就是运用了;相关文章推荐
- 通过超链接打开App应用
- 【支付】Cocos2d-x IOS内购(IAP支付)
- ERROR: Android Source Generator: [project] AndroidManifest.xml file not found
- 自定义Dialog,toast
- Swift入门基础语法
- vs xamarin android 监听返回键退出程序
- android studio 运行代码时识别genymotion设备
- Android中Handler引起的内存泄露
- Android 虚拟机 libdvm.so 与 libart.so
- CVPR 2014 ObjectnessBING 原文翻译
- iOS越狱环境开发
- iOS开发之CGPoint、CGSize、CGRect、CGRectMake、window(窗口)、视图(view)
- cocos2d-x中shader的使用
- AndroidManifest.xml——activity(四)
- [原创][下载]Senparc.Weixin.MP-微信公众平台SDK(C#) - 已支持微信6.x API
- iOS 枚举类型
- 怎么看app 是webapp还是原生app
- 【iOS】网页中调用JS与JS注入
- vs xamarin android StartActivity
- APP注册名称的一些问题