Android volley和webview同步cookies

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

说白了总结就如下:

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;

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:

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;

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的存在与否取决于服务端的设置,我们客户端也只是接收或者保存服务器的数据;有些人可能会遇到用了以上方式还是不行,那就得与你的服务端开发人员多交流了,他们的设置可能会对客户端或者浏览器产生一定的影响;也希望大家多尝试,原理其实很简单,剩下的就是运用了;

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值