最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

【已解决】Android中的HttClient处理过程中,如何自动处理Cookie:发送Cookie,获得返回的Cookie,合并新旧的Cookie

Android crifan 5065浏览 0评论

【问题】

在折腾:

【已解决】Android中利用HttpClient等库实现网络文件下载

的过程中,需要处理HttpClient中的Cookie。

【解决过程】

1.参考:

Android 上的 HttpClient 的 Cookie 存取策略

的值,httpClient,有setCookieStore等函数。

2.所以去代码中,自己试试,结果没有。

3.参考:

Http cookie store in Android

但是结果写出相关的代码:

		try{
			
			//parse name/value from mCookies[0]. If you have more than one cookie, a for cycle is needed.
			Cookie cookie = new BasicClientCookie("name", "value");
			localCookies.addCookie(cookie);
			
			HttpContext localContext = new BasicHttpContext();
			localContext.setAttribute(ClientContext.COOKIE_STORE, localCookies);
			
			response = httpClient.execute(request, localContext);
	        
			if(response.getStatusLine().getStatusCode()==HttpStatus.SC_OK){
				
				HttpEntity respEnt = response.getEntity();
				if(htmlCharset != null)
				{
					respHtml = EntityUtils.toString(respEnt, htmlCharset);
				}
				else
				{
					System.out.println(respEnt.isChunked());
					System.out.println(respEnt.isStreaming());
				}
	        }
	        
        } catch (ClientProtocolException cpe) {
            // TODO Auto-generated catch block
        	cpe.printStackTrace();    
        } catch (IOException ioe) {
            // TODO Auto-generated catch block
        	ioe.printStackTrace();
        }

结果觉得还是有问题。

无法实现,自动的,发送和接受,对应的cookie。

4.参考:

Java 用HttpClient发送Cookie

说是请求后,可以从DefaultHttpClient得到cookie。去试试。

但是我这里的是:

HttpClient httpClient = new DefaultHttpClient();

结果没有获得cookie的函数getCookieStore

所以改为:

DefaultHttpClient httpClient = new DefaultHttpClient();

就有了:

httpClient.getCookieStore();

好了,此处,可以通过:

BasicCookieStore respCookies = (BasicCookieStore) httpClient.getCookieStore();

去获得返回的cookie了。

5.接下来,要想办法去发送cookie。

此时,就可以直接通过:

httpClient.setCookieStore(localCookies);

去设置对应的cookie了。

6.接下来,还要去实现,将返回的respCookies,合并到整个的cookie值localCookies中。

折腾了半天,用了这样的代码:

DefaultHttpClient httpClient = new DefaultHttpClient();
HttpUriRequest request;
HttpResponse response;

BasicCookieStore localCookies = new BasicCookieStore();

//http://www.pocketdigi.com/20110521/296.html
httpClient.setCookieStore(localCookies);
response = httpClient.execute(request);
BasicCookieStore respCookies = (BasicCookieStore) httpClient.getCookieStore();
localCookies = respCookies;

然后是可以获得返回的cookie的:

got resp cookie

7.现在继续调试,看看能否真正的发送cookie,以及如何合并cookie。

结果发现,通过:

localCookies = respCookies;

会把之前的cookie冲掉,所以现在想办法去合并,或者说管理cookie。

结果是,使用这样的代码:

			httpClient.setCookieStore(localCookies);
			response = httpClient.execute(request);
			//get cookies
			//BasicCookieStore respCookies = (BasicCookieStore) httpClient.getCookieStore();
			CookieStore respCookies = httpClient.getCookieStore();
			// update cookies
			//localCookies = respCookies;
			List<Cookie> respCookieList = respCookies.getCookies();
			for(Cookie ck : respCookieList)
			{
				localCookies.addCookie(ck);
			}

结果导致程序崩溃了。

在for循环中,不知道哪个步骤,估计是:

localCookies.addCookie(ck);

导致程序异常死掉,调试中断了。

8.网上找了半天,竟然没有找到解释清楚,如何:

自动发送cookie的

自动获得cookie的

关键是,将获得的cookie,和之前的cookie合并的

9.重新调试一次,看看到底哪里出错了。

此时调试过程中,获得了多个返回的cookie:

[[version: 0][name: valid][value: 1][domain: songtaste.com][path: /][expiry: Sun Jan 20 15:57:29 GMT+08:00 2013],

[version: 0][name: valid][value: 1][domain: .songtaste.com][path: /][expiry: Sun Jan 20 15:57:29 GMT+08:00 2013],

[version: 0][name: PHPSESSID][value: 04200d169f38ce5ea3e41b97eaf4c575][domain: songtaste.com][path: /][expiry: null]]

然后结果好像还是,在加入第二个cookie:

[version: 0][name: valid][value: 1][domain: .songtaste.com][path: /][expiry: Sun Jan 20 15:57:29 GMT+08:00 2013],

时就挂了,好像无法加入此cookie的感觉。

10.参考:

[TIMOB-6925] Android cookie sync to share cookies between HTTPClient and WebViews

去搜索CookieManager,然后发现其实这里:

Custom CookieManager

也有此CookieManager。

参考其代码,自己试试:

	CookieStore localCookies = null;
	CookieManager localCm = null;
	
	public crifanLib()
	{
		localCookies = new BasicCookieStore();
		
		localCm = new CookieManager();
		localCm.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
	}

    java.net.CookieStore currentCookies =localCm.getCookieStore();
    response = httpClient.execute(request);
    java.net.CookieStore respCookies =localCm.getCookieStore();
			

结果还是不行,根本没有管理起来。

11.参考:

使用CookieHandler,CookieManager和CookieStore获取Cookie

去试试代码:

加了handler了,变成:

		localCm = new CookieManager();
		localCm.setCookiePolicy(CookiePolicy.ACCEPT_ALL);
		CookieHandler.setDefault(localCm);

结果还是不行。

12.最后,还是用之前的代码,才可以正确的处理cookie:

			HttpContext localContext = new BasicHttpContext();
			localContext.setAttribute(ClientContext.COOKIE_STORE, localCookies);
			response = httpClient.execute(request, localContext);
			List<Cookie> respCookieList = localCookies.getCookies();

结果是,可以自动处理cookie的。

至少我这里,后来发送cookie过去后,返回后,得到的cookie,没有被清空。

 

【总结】

目前,貌似这样的代码,是可以正确自动的,处理cookie的,即:

发送http请求前,设置cookie;

可以自动获得返回的cookie;

关键是,可以自动合并新旧的cookie,使得当前的cookie,是最新的,合并后的值;

对应可以工作的代码是:

import org.apache.http.protocol.BasicHttpContext;
import org.apache.http.protocol.HttpContext;
import org.apache.http.client.protocol.ClientContext;
import org.apache.http.impl.client.DefaultHttpClient;
import java.util.List;
import org.apache.http.cookie.Cookie;

CookieStore localCookies = null;
localCookies = new BasicCookieStore();
DefaultHttpClient httpClient = new DefaultHttpClient();

HttpResponse response;

HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE, localCookies);
response = httpClient.execute(request, localContext);

List<Cookie> respCookieList = localCookies.getCookies();
for(Cookie ck : respCookieList)
{
    System.out.println(ck);
}

也许以后还可以进一步优化。

转载请注明:在路上 » 【已解决】Android中的HttClient处理过程中,如何自动处理Cookie:发送Cookie,获得返回的Cookie,合并新旧的Cookie

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (2)

  1. 你的方法没有错,从哪个Http的原理上来所,Cookie就是这么进行操作的。你可要抓一下正常浏览器访问的请求过程。应该,本该如此。
    darkread8年前 (2016-07-22)回复
  2. localCookies = new BasicCookieStore(); 這一行會顯示錯誤 會要求我add cast to (CookieStore)
    Jonah8年前 (2016-06-11)回复
86 queries in 0.172 seconds, using 22.15MB memory