java - HttpClient 4.x 如何使用cookie?

标签 java http cookies httpclient

我正在尝试使用通过 HttpClient 4.0.3 响应我的 post 方法而获得的 cookie ;

这是我的代码:

public void generateRequest()
{
    DefaultHttpClient httpclient = new DefaultHttpClient();
    HttpPost httppost = new HttpPost("http://mysite.com/login");
    httpclient.getParams().setParameter("http.useragent", "Custom Browser");
    httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION,
            HttpVersion.HTTP_1_1);
    httpclient.getParams().setParameter(ClientPNames.COOKIE_POLICY,
            CookiePolicy.BROWSER_COMPATIBILITY);

    CookieStore cookieStore = new BasicCookieStore();
    HttpContext localContext = new BasicHttpContext();
    localContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);

    try
    {
        LOG.info("Status Code: sending");
        List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
        nameValuePairs.add(new BasicNameValuePair("email", "john%40gmail.com"));
        nameValuePairs.add(new BasicNameValuePair("password", "mypassword"));
        httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
        httppost.setHeader("ContentType", "application/x-www-form-urlencoded");
        HttpResponse response = httpclient.execute(httppost, localContext);
        HttpEntity entity = response.getEntity();
        if (entity != null)
        {
            entity.consumeContent();
        }
        iterateCookies(httpclient);

    }
    catch (ClientProtocolException e)
    {
        LOG.error("ClientProtocolException", e);
    }
    catch (IOException e)
    {
        LOG.error("IOException", e);
    }
}

private void iterateCookies(DefaultHttpClient httpclient)
{
    List<Cookie> cookies = httpclient.getCookieStore().getCookies();
    if (cookies.isEmpty())
    {
        System.out.println("No cookies");
    }
    else
    {
        for (Cookie c : cookies)
        {
            System.out.println("-" + c.toString());
        }
    }
}

但我不断收到 No cookies即使当我使用 web-sniffer.net 时也已注销,我收到以下响应:

Status:            HTTP/1.1 302 Found
Cache-Control:     private, no-store    
Content-Type:      text/html; charset=utf-8 
Location:          http://www.mysite.com/loginok.html   
Server:            Microsoft-IIS/7.0    
X-AspNet-Version:  2.0.50727    
Set-Cookie:        USER=DDA5FF4E1C30661EC61CFA; domain=.mysite.com; expires=Tue, 08-Jan-2013     18:39:53 GMT; path=/   
Set-Cookie:        LOGIN=D6CC13A23DCF56AF81CFAF; domain=.mysite.com; path=/ Date: Mon, 09     Jan 2012 18:39:53 GMT 
Connection:        close    
Content-Length:    165

我在网上找到的所有有意义的示例都引用 HttpClient 3.x,您可以在其中设置 CookiePolicyIGNORE并处理Set-Cookie手动 header 。我不明白为什么这在 4.x 中如此困难。我需要访问USER哈希有多种原因。谁能告诉我到底如何才能访问它?

更新

我发现了以下C#代码执行相同的操作并且工作正常。

private static string TryGetCookie(string user, string pass, string baseurl)
    {
        string body = string.Format("email={0}&password={1}", user, pass);
        byte[] bodyData = StringUtils.StringToASCIIBytes(body);

        HttpWebRequest req = WebRequest.Create(baseurl) as HttpWebRequest;

        if (null != req.Proxy)
        {
            req.Proxy.Credentials = CredentialCache.DefaultCredentials;
        }

        req.AllowAutoRedirect = false;
        req.Method = "Post";
        req.ContentType = "application/x-www-form-urlencoded";
        req.ContentLength = bodyData.Length;

        using (Stream reqBody = req.GetRequestStream())
        {
            reqBody.Write(bodyData, 0, bodyData.Length);
            reqBody.Close();
        }

        HttpWebResponse resp1 = req.GetResponse() as HttpWebResponse;

        string cookie = resp1.Headers["Set-Cookie"];

        if( string.IsNullOrEmpty(cookie))
        {
            if (0 < resp1.ContentLength)
            {
                // it's probably not an event day, and the server is returning a singlecharacter
                StreamReader stringReader = new StreamReader(resp1.GetResponseStream());

                return stringReader.ReadToEnd();
            }

            return null;
        }

        return ParseCookie(cookie);
    }

我相信我的 java 代码没有正确形成 post 请求,因为当我使用 URLConnection 并从下面的 web-sniffer.net 打印请求 header 时:

POST /reg/login HTTP/1.1[CRLF]
Host: live-timing.formula1.com[CRLF]
Connection: close[CRLF]
User-Agent: Web-sniffer/1.0.37 (+http://web-sniffer.net/)[CRLF]
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7[CRLF]
Cache-Control: no-cache[CRLF]
Accept-Language: de,en;q=0.7,en-us;q=0.3[CRLF]
Referer: http://web-sniffer.net/[CRLF]
Content-type: application/x-www-form-urlencoded[CRLF]
Content-length: 53[CRLF]
[CRLF]
email=john%40gmail.com&password=mypassword

我从服务器收到包含 set-cookies 的响应 header 。我的java代码没有生成与web-sniffer.net相同的请求吗?

我看到了使用此代码生成的 post 方法:

PostMethod authPost = new PostMethod("http://localhost:8000/webTest/j_security_check");
// authPost.setFollowRedirects(false);
NameValuePair[] data = {
new NameValuePair("email", "john%40gmail.com"),
new NameValuePair("password", "mypassword")
};
authPost.setRequestBody(data);
status = client.executeMethod(authPost); 

这里的主要区别是NameValuePair数据设置在请求正文中,而不是设置为实体。这有什么区别吗?这会产生正确的请求 header 吗?

最佳答案

两个 cookie 看起来都很可疑。两者都使用过时的 Netscape cookie 草稿格式。两者都有无效的域属性值。除此之外,LOGIN 显示格式错误(路径属性后缺少分号)。因此,很可能两个 cookie 都被 HttpClient 拒绝。

您可以通过在打开上下文日志记录的情况下运行 HttpClient 来查明是否属于这种情况,如下所述: http://hc.apache.org/httpcomponents-client-ga/logging.html

最后一点。一般来说,在使用 HttpClient 4.x 时不应干预 cookie 策略。默认的 BEST_MATCH 策略将根据 Set-Cookie header 值的组成自动将 cookie 的处理委托(delegate)给特定的 cookie 规范实现。为了完全禁用 cookie 处理,应该从协议(protocol)处理链中删除 cookie 处理协议(protocol)拦截器。

希望这有帮助。

关于java - HttpClient 4.x 如何使用cookie?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8795911/

相关文章:

java - 如何在 Java/Scala 中动态、递归地修饰一个类?

java - 如何配置 Hibernate 以使用 SSL 与数据库服务器通信?

java - 域对象和 Controller 类

rest - 使用一次性密码来保护 REST 应用程序是个好主意吗?

c# - 登录网站并使用 cookie 获取另一个页面的源代码

javascript - 如何使用 Javascript 和 Jquery Vector Map 设置 session

java - 安卓 : Get new position of View after animation

http - http2 TCP 连接何时关闭?

php - 如何抑制/删除 PHP session cookie

http - 服务器在来自 SIM908 的几次 GET 请求后禁用页面