webView中cookie的处理:webView+cookie+okhttp

来源:互联网 发布:扣图算法 灰度图像 编辑:程序博客网 时间:2024/05/17 04:16

之前项目开发中涉及到webView时候遇到过cookie问题,当时也没有搞明白持久化、同步、清除这些概念,
就copy了代码到项目里,今天总结下:

关于cookie的介绍参考下面帖子吧:
http://blog.csdn.net/fangaoxin/article/details/6952954
http://blog.csdn.net/ghsau/article/details/20395681
http://www.tuicool.com/articles/IRBZjm

1.我们android始终有网络请求但也没有出现过cookie的问题,所以先说下为什么webView使用的时候会出现cookie的问题:
默认情况下,android应用中的httpClient和第三方的网络请求框架保存的cookie都是非永久性的,
而我们在android应用中打开web页面的逻辑基本都是用户已登录状态之后的操作逻辑,而web请求
属于HTTP无连接状态协议的请求,每个请求之间是相互独立没有联系的,登陆状态需要靠cookie来
保存,这时候就出现了我们打开的web页面始终是登陆页的问题,因为web并不知道你在android客户
端已经登陆了因为你打开web的url中并没有携带它想要的cookie。

2.解决方法:
so,如果希望url能够打开期望的web页面,就必须携带保存着已登陆用户信息的cookie,这个cookie就在android中的
HttpClient中,但正如上面所说这些cookie并不是持久性的所以我们无法获得,因为cookie的持久化保存对于app来说
是影响性能并且没有意义的。这时我们就需要在请求web的URL的接口的时候把cookie持久化,然后在webActivity中把
HttpClient中的持久化cookie同步到将要打开的URL中,最后再退出webActivity的时候清除HttpClient中的cookie。

3.如何持久化网络请求中cookie、如何同步网络请求中cookie到web的url中、如何清除cookie?

3.1 持久化cookie:
首先在Application类中添加如下代码:
public class MyApplication extends Application {
。。。。。。

//A persistent cookie store,即一个持久化的cookie仓库private PersistentCookieStore myCookieStore;//获取持久化的cookiepublic PersistentCookieStore getMyCookieStore() {    if (myCookieStore == null)        myCookieStore = new PersistentCookieStore(this);    return myCookieStore;}//清除cookiepublic void clearCookies(Context context) {    if (myCookieStore == null) {        myCookieStore = new PersistentCookieStore(context);    }    myCookieStore.removeAll();}。。。。。。

}
接下来是我们封装的可以提供持久化cookie的网络请求代码的封装:
/**
* post 提交–持久化cookies
*
* @param activity
* @param url
* @param obj
* @param callback
*/
public static void postWeb(final Activity activity, String url, JSONObject obj) {
//重新创建一个OkHttpClient对象做网络请求,因为只有这个请求需要持久化cookie,应用中的其它请求并不需要
OkHttpClient client = new OkHttpClient();
client.setCookieHandler(new CookieManager(MyApplication.getInstance().getMyCookieStore(), CookiePolicy.ACCEPT_ALL));

    //请求参数    FormEncodingBuilder builder = new FormEncodingBuilder();    Map<String, String> params = getSbParams(obj);    for (String key : params.keySet()) {        builder.add(key, params.get(key));    }    final Request request = new Request.Builder()            .url(url)            .post(builder.build())            .build();    Call call = client.newCall(request);    call.enqueue(new Callback() {        @Override        public void onFailure(final Request request, final IOException e) {            activity.runOnUiThread(new Runnable() {                @Override                public void run() {                    //TODO                }            });        }        @Override        public void onResponse(final Response response) throws IOException {            final String res = response.body().string();            LogUtils.e("log--返回数据:res = " + res);            //TODO        }    });}

3.2 同步网络请求中cookie到web的url中:
在要跳转到需要登陆之后才能进入的web页的时候,需要对url进行cookie同步,代码如下:
public static void synCookies(Context context, String url) {
//CookieSyncManager负责管理webView中的cookie
CookieSyncManager.createInstance(context);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
List cookies = MyApplication.getInstance().getMyCookieStore().getCookies(); //获取okhttp网络请求中持久化的cookie
for (int i = 0; i < cookies.size(); i++) {
HttpCookie cookie = cookies.get(i);
if (cookie.getName().equals(“PHPSESSID”)) {
// cookies是在HttpClient中获得的cookie,这里是从okhttp中获得,加入到webView的cookie中
cookieManager.setCookie(url, cookie.getName() + “=” + cookie.getValue());
}
}
CookieSyncManager.getInstance().sync();
}

3.3 退出WebActivity之前需要清除cookie:
private void close() {
//清除WebView中cookie
CookieSyncManager.createInstance(this);
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
cookieManager.removeSessionCookie();
//清除okhttp中cookie
MyApplication.getInstance().clearCookies(this);
//关闭WebActivity
finish();
}

注意:项目开发中具体需不需要客户端做cookie的持久化,取决于接口和h5开发人员的处理。cookie的持久化就是为了
保存用户的登陆状态,而如果接口端通过请求参数中本地保存的用户信息可以判断登陆状态,那么客户端可能就不需要
通过持久化cookie来实现登陆状态的保存。

另附webview中js防注入漏洞处理总结:
参考:
http://mp.weixin.qq.com/s?__biz=MzAxMTI4MTkwNQ==&mid=2650820122&idx=1&sn=bff5bf04bc97a32f6d4b7f4c41935cb1&scene=23&srcid=0601hNrslBeRYF5nQFVlwr8i#rd
http://blog.csdn.net/qy274770068/article/details/51243751
https://github.com/pedant/safe-java-js-webview-bridge
实际使用总结:
实际使用中我们可以不引入第三方库,只需要拷贝如下三个方法到本地工程中:
InjectedChromeClient、JsCallback、JsCallJava,然后创一个类继承InjectedChromeClient即可。

2 0
原创粉丝点击