【场景描述】
通过Android 4.0.4 WebView内嵌服务端数据列表展示页面,且页面内点击某条数据需要Ajax动态加载数据明细。
说明:
1、服务端需要对客户端进行认证。
2、内嵌的Web页面采用同样的认证方式。
【实现方案】
1、客户端通过HttpClient调用服务端接口进行登录,然后再或者登录后服务端返回的Cookie信息并将其保存到全局静态变量。
DefaultHttpClient defaultHttpClient =new DefaultHttpClient(); HttpResponse httpResponse = defaultHttpClient.execute(httpRequest); CookieStore cookieStore = ((AbstractHttpClient) defaultHttpClient).getCookieStore(); cookies=cookieStore.getCookies();
2、通过WebView加载页面的时候,遍历上一步缓存的Cookie,分别加入当前访问的URL。
CookieSyncManager.createInstance(this); CookieManager cookieManager = CookieManager.getInstance(); cookieManager.setAcceptCookie(true); for (int i = 0; i < cookies.size(); i++) { Cookie cookie = cookies.get(i); cookieManager.setCookie(this.url, cookie.getName() + "=" + cookie.getValue()); } CookieSyncManager.getInstance().sync(); mWebView.loadUrl(this.url);
【现象】
1、内嵌的列表查询页面可以正常访问,但点击明细查询,通过Ajax动态加载其它页面的时候服务端始终返回登录页面。
2、通过WireShark查看,发现内嵌的列表页面访问的HTTP报文里面有两个相同的Cookie name=JSessionid(Tomcat用这个保持回话),如下:(CSDN这个图片功能不好用)
【推理和分析】
1、尝试直接在Android浏览器打开服务端页面是OK的,且PC端浏览器打开也没有问题,不会出现两个JSessionid。
2、查询WebView API,最后分析出在设置Cookie的时候没有加“path”。(省略一堆推理过程,本人比较懒)
【解决方案】
直接在每个Cookie设置项里面增加“path=/”,问题即可解决,代码如下(红色部分):
for (int i = 0; i < cookies.size(); i++) { Cookie cookie = cookies.get(i); cookieManager.setCookie(this.url, cookie.getName() + "=" + cookie.getValue()<span style="color:#ff0000;"><strong>+";path=/;"</strong></span>); }
最后,希望对大家有所帮助。