如何在 Android 和/或 Java 中使用 HttpClient 管理 cookie?

Posted

技术标签:

【中文标题】如何在 Android 和/或 Java 中使用 HttpClient 管理 cookie?【英文标题】:How do I manage cookies with HttpClient in Android and/or Java? 【发布时间】:2010-08-27 18:53:39 【问题描述】:

我正在尝试登录一个站点并维护该会话/cookie,以便服务器识别我的登录,但我正在努力找出一种从响应中提取 cookie 并将其设置为维护我的请求的方法登录。我想知道是否应该使用标题“Set-Cookie”或使用 CookieStore。任何帮助是极大的赞赏。这是我的代码,我认为 getHeader/getCookie 方法可以使用 cmets。

public class Http

DefaultHttpClient client = new DefaultHttpClient();
HttpGet request;
HttpEntity entity;
HttpResponse response;
HttpPost post;
CookieStore cookieStore = new BasicCookieStore();
HttpContext localContext = new BasicHttpContext();

public static void setContext()

    localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);


public static void getPage(String url) throws Exception

    request = new HttpGet(url);
    response = client.execute(request, localContext);
    PARSER.preParse(url, response);


public static HttpResponse postPage(List<NameValuePair> params, String host, String action) throws Exception

    post = new HttpPost(host + action);
    post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));

    response = client.execute(post, localContext);

    entity = response.getEntity();
    if(entity != null)
    
        entity.consumeContent();
    

    return response;



public void destoyHttp()

    client.getConnectionManager().shutdown();


希望其他人更好地理解我的困惑,我添加了我知道可以工作并维护会话的代码,但是当我尝试将代码移动到我的实际应用程序中时,它在某处中断了。

public class HttpClientTest extends Activity

DefaultHttpClient client = new DefaultHttpClient();
HttpGet request;
HttpEntity entity;
List<Cookie> cookies;
HttpResponse response;
HttpPost post;

@Override
public void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);
    try 
        getRequest();
     catch (Exception e) 
        Log.d("My Activity", "Failed");
        e.printStackTrace();
    


public void getRequest() throws Exception

    final String TAG = "MyActivity";
    request = new HttpGet("http://gc.gamestotal.com/i.cfm?p=login&se=4");
    response = client.execute(request);

    String action = "i.cfm?&1028&p=login&se=4";
    String yourServer = "http://gc.gamestotal.com/";
    post = new HttpPost(yourServer + action);

    List<NameValuePair> params = new ArrayList<NameValuePair>();
    params.add(new BasicNameValuePair("nic", "myusername"));
    params.add(new BasicNameValuePair("password", "mypassword"));
    params.add(new BasicNameValuePair("server", "4"));

    post.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8));


    response = client.execute(post);
    entity = response.getEntity();

    if(entity != null)
        entity.consumeContent();
    

    request = new HttpGet("http://gc.gamestotal.com/i.cfm?f=com_empire&cm=3");

    response = client.execute(request);

    if(entity != null)
    
        entity.consumeContent();
        




我知道它确实有效,您可以看到在这段代码中我使用了内容(),但将其添加到顶部代码似乎并没有什么不同,所以我将其省略了。有什么想法吗?

编辑:我仍然无法让代码保持会话继续进行。我正在发布我当前代码中的 cookie,以及正在运行的第二个代码的 cookie。也许有人会注意到一个问题,我当然不会。

08-31 06:53:50.318: VERBOSE/SFGC(496): - [version: 0][name: CFID][value: 26651316][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]
08-31 06:53:50.329: VERBOSE/SFGC(496): - [version: 0][name: CFTOKEN][value: 96917381][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]
08-31 06:53:50.329: VERBOSE/SFGC(496): - [version: 0][name: CFCLIENT_SFGC_106Y][value: CFTOKEN2%3D735125416524430%23COUNTRY%3D56%23DOWNLOADFLAG%3D0%23OCHAT%3D1%23PM%5FDATE%3D%7Bts+%272010%2D08%2D31+14%3A53%3A45%27%7D%23REGION%3D3%23SCREEN%3D800%23S%5FGC%5FIMAGELOC%3Di%2Fw%2F%23TIMEZONE%3D%2D600%23][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]
08-31 06:53:50.339: VERBOSE/SFGC(496): - [version: 0][name: CFGLOBALS][value: HITCOUNT%3D2%23LASTVISIT%3D%7Bts+%272010%2D08%2D31+14%3A53%3A45%27%7D%23TIMECREATED%3D%7Bts+%272010%2D08%2D31+14%3A53%3A39%27%7D%23][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]

08-31 06:53:51.938: VERBOSE/SFGC(496): - [version: 0][name: CFID][value: 26651316][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]
08-31 06:53:51.938: VERBOSE/SFGC(496): - [version: 0][name: CFTOKEN][value: 96917381][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]
08-31 06:53:51.938: VERBOSE/SFGC(496): - [version: 0][name: CFCLIENT_SFGC_106Y][value: CFTOKEN2%3D735125416524430%23COUNTRY%3D56%23DOWNLOADFLAG%3D0%23OCHAT%3D1%23PM%5FDATE%3D%7Bts+%272010%2D08%2D31+14%3A53%3A45%27%7D%23REGION%3D3%23SCREEN%3D800%23S%5FGC%5FIMAGELOC%3Di%2Fw%2F%23TIMEZONE%3D%2D600%23][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]
08-31 06:53:51.948: VERBOSE/SFGC(496): - [version: 0][name: CFGLOBALS][value: HITCOUNT%3D3%23LASTVISIT%3D%7Bts+%272010%2D08%2D31+14%3A53%3A46%27%7D%23TIMECREATED%3D%7Bts+%272010%2D08%2D31+14%3A53%3A39%27%7D%23][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]


08-31 06:52:41.628: DEBUG/MyActivity(469): - [version: 0][name: CFID][value: 26651274][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]
08-31 06:52:41.638: DEBUG/MyActivity(469): - [version: 0][name: CFTOKEN][value: 58361320][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]
08-31 06:52:41.638: DEBUG/MyActivity(469): - [version: 0][name: CFCLIENT_SFGC_106Y][value: CFTOKEN2%3D735125815099420%23COUNTRY%3D56%23DOWNLOADFLAG%3D0%23OCHAT%3D1%23PM%5FDATE%3D%7Bts+%272010%2D08%2D31+14%3A52%3A36%27%7D%23REGION%3D3%23SCREEN%3D800%23S%5FGC%5FIMAGELOC%3Di%2Fw%2F%23TIMEZONE%3D%2D600%23][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]
08-31 06:52:41.648: DEBUG/MyActivity(469): - [version: 0][name: CFGLOBALS][value: HITCOUNT%3D2%23LASTVISIT%3D%7Bts+%272010%2D08%2D31+14%3A52%3A36%27%7D%23TIMECREATED%3D%7Bts+%272010%2D08%2D31+14%3A52%3A33%27%7D%23][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]

08-31 06:52:44.138: DEBUG/MyActivity(469): - [version: 0][name: CFID][value: 26651274][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]
08-31 06:52:44.138: DEBUG/MyActivity(469): - [version: 0][name: CFTOKEN][value: 58361320][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]
08-31 06:52:44.138: DEBUG/MyActivity(469): - [version: 0][name: CFCLIENT_SFGC_106Y][value: CFTOKEN2%3D735125815099420%23COUNTRY%3D56%23DOWNLOADFLAG%3D0%23OCHAT%3D1%23PM%5FDATE%3D%7Bts+%272010%2D08%2D31+14%3A52%3A36%27%7D%23REGION%3D3%23SCREEN%3D800%23S%5FGC%5FIMAGELOC%3Di%2Fw%2F%23TIMEZONE%3D%2D600%23][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]
08-31 06:52:44.138: DEBUG/MyActivity(469): - [version: 0][name: CFGLOBALS][value: HITCOUNT%3D4%23LASTVISIT%3D%7Bts+%272010%2D08%2D31+14%3A52%3A38%27%7D%23TIMECREATED%3D%7Bts+%272010%2D08%2D31+14%3A52%3A33%27%7D%23][domain: gc.gamestotal.com][path: /][expiry: Sun Sep 27 00:00:00 GMT+00:00 2037]

【问题讨论】:

【参考方案1】:

您需要使用 HttpContext。将 cookie 存储设置为上下文,并在执行方法中使用 HttpGet/HttpPost 长时间传递上下文。希望这会有所帮助。

查看示例:完整代码可在here找到

   // Create a local instance of cookie store
    CookieStore cookieStore = new BasicCookieStore();

    // Create local HTTP context
    HttpContext localContext = new BasicHttpContext();
    // Bind custom cookie store to the local context
    localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

    HttpGet httpget = new HttpGet("http://www.google.com/"); 

    System.out.println("executing request " + httpget.getURI());

    // Pass local context as a parameter
    HttpResponse response = httpclient.execute(httpget, localContext);

【讨论】:

好的,我将如何获取标题?我是否从响应中获取它,例如 response.getHeader("Set-Cookie")?因为我试图做类似的事情但只有一个 getHeaders();我猜的方法返回一个数组?我得再查一遍。 好的,我设法使用了 Header[] 对象并成功设置了包括 Cookie 标头在内的标头,但这似乎并没有解决我的问题。我已经用我制作的代码编辑了我的问题,但由于某种原因,当我将它移到我的实际应用程序时它坏了。仅供参考,工作代码对标题没有任何作用,它只是工作吗?大声笑 Ok ;) 我设法找到了您的代码中缺少的东西并更新(相当改变)我的答案。 感谢您的快速回复。我添加了缺少的代码,但仍然没有运气。将 GET 和 POST 部分拆分为 2 个不同的方法会以某种方式导致客户端不保留会话吗? 您是否尝试将 cookiestore 设置为 HttpContext 并在执行 httpclient 时将 HttpContext 与您的方法一起传递?【参考方案2】:

我无法让我自己的代码正常工作(我可能稍后会再次工作),但我在这里找到了有用的代码 android project using httpclient --> http.client (apache), post/get method 并且我正在使用 Charlie Collins 构建的类,它类似于 Http 代码ZXing Android 示例。我可能最终会转向 ZXing 代码。

【讨论】:

【参考方案3】:

对我来说,它不起作用,直到我将 HttpContext 和 CookieStore 都设为静态,以保留所有请求。

【讨论】:

以上是关于如何在 Android 和/或 Java 中使用 HttpClient 管理 cookie?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 OS Lollipop 在 Java 中为 Android 裁剪图像

如何在 AsyncTask 或 RequestHandler.java 中添加基本的 auth java android?

如何在 Android 上重新启动 Qt 或 c++ 中的程序?

如何根据 android studio 中的 listview 项目点击更改活动图像和文本? java 或 kotlin

JAVA Eclipse开发Android如何让屏幕保持为竖直或水平状态

带有 Java 和 Kotlin 文件、kapt 或 annotationProcessor 的 Android 项目?