带有 CookieManager 的 HttpURLConnection 是不是应该自动处理会话 cookie?

Posted

技术标签:

【中文标题】带有 CookieManager 的 HttpURLConnection 是不是应该自动处理会话 cookie?【英文标题】:Should HttpURLConnection with CookieManager automatically handle session cookies?带有 CookieManager 的 HttpURLConnection 是否应该自动处理会话 cookie? 【发布时间】:2013-01-29 09:14:12 【问题描述】:

我有一个 Java 应用程序 (JDK 1.7.0_13),并且正在使用 java.net.HttpURLConnection 连接到一些基于 servlet 的服务,这些服务进行会话管理。我想弄清楚如何使用 java.net.CookieManager 来跟踪会话 cookie。阅读文档我得到的印象是使用 CookieHandler.setDefault(new CookieManager()) 安装 CookieManager 应该会导致 cookie 管理自动发生。但是,对同一 URL 的多个请求似乎不会保留 cookie。我是否必须手动从响应中提取 cookie 并自行在请求中重新发送它们,还是 CookieManager 会自动为我执行此操作?如果 CookieManager 没有,那么它增加了什么价值?

为了进行测试,我有一个 servlet,每次浏览器访问 URL 时都会成功地增加一个计数器。这在 Safari、FireFox 和 Chrome 中运行良好……但是,我无法在独立的 Java 应用程序中运行它。

这是一个非常简单的测试程序来说明我希望简单的工作。它在开始时安装 CookieManager,然后在控制台输入 URL 时重复调用 fetch(String urlString) 方法。

package com.brilliant.experimental;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpFetcher   
    public static void fetch(String urlString) 
        try 
            URL url = new URL(urlString);
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            InputStream in = conn.getInputStream();
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));
            int status = conn.getResponseCode();
            System.out.println("Status = " + status);
            String key;
            System.out.println("Headers-------start-----");
            for (int i = 1; (key = conn.getHeaderFieldKey(i)) != null; i++) 
                System.out.println(key + ":" + conn.getHeaderField(i));
            
            System.out.println("Headers-------end-----");
            System.out.println("Content-------start-----");
            String inputLine;
            while ((inputLine = reader.readLine()) != null) 
                System.out.println(inputLine);
            
            System.out.println("Content-------end-----");
            in.close();
         catch (Exception e) 
            System.out.println(e);
        
    

    public static void main(String[] args) 
        CookieHandler.setDefault(new CookieManager());

        for (int i = 0; i < args.length; i++) 
            fetch(args[i]);
        

        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader reader = new BufferedReader(isr);
        String prompt = "> ";
        String urlString;
        try 
            for (System.out.print(prompt);
                    (urlString = reader.readLine()) != null; 
                    System.out.print(prompt)) 
            
                fetch(urlString);
            
         catch (IOException ioe) 
            System.out.println(ioe);
        
    


从这个应用程序调用我的 servlet 显然会从服务器返回一个会话 cookie。但是,再次调用会获得一个新的会话 cookie。

> http://localhost:8080/brilliant/TestServlet
Status = 200
Headers-------start-----
Server:Resin/4.0.34
Cache-Control:private
Set-Cookie:JSESSIONID=aaaMp0uKke4gp9_-nUuZt; path=/
Content-Length:19
Date:Wed, 13 Feb 2013 18:02:31 GMT
Headers-------end-----
Content-------start-----
Session count is 0
Content-------end-----
> http://localhost:8080/brilliant/TestServlet
Status = 200
Headers-------start-----
Server:Resin/4.0.34
Cache-Control:private
Set-Cookie:JSESSIONID=aaaZ-oPaC1I9WdEDoUuZt; path=/
Content-Length:19
Date:Wed, 13 Feb 2013 18:02:33 GMT
Headers-------end-----
Content-------start-----
Session count is 0
Content-------end-----

所以,总而言之,我是否必须做一些其他事情才能让 CookieManager 自动为我工作,或者我是否必须求助于从响应中手动提取 cookie 并将它们与请求一起重新发送?

【问题讨论】:

请移步***.com/questions/12349266/…。最佳解决方案已经出现。 【参考方案1】:

我运行你的代码并替换它

CookieHandler.setDefault(new CookieManager()); 

CookieHandler.setDefault( new CookieManager( null, CookiePolicy.ACCEPT_ALL ) );

成功了!

【讨论】:

谢谢。工作出色。当然,既然我知道了答案,文档就很容易找到了。 ;-) 这是一个比您通常可以找到的更好且更紧凑的答案。谢谢! 这会自动将 cookie 添加到 CookieStore 还是我每次都必须写 cookieManager.getCookieStore().add(uri,hc);hcHttpCookie Object 这只适用于第一次..当我重新启动应用程序时..它给我错误 BasicNetwork.performRequest: Unexpected response code 401 ..请帮忙!

以上是关于带有 CookieManager 的 HttpURLConnection 是不是应该自动处理会话 cookie?的主要内容,如果未能解决你的问题,请参考以下文章

android setCookie 免登录

Jmeter---Http Cookie Manager

JMeter之Http Cookie Manager

Twitter4j,我如何注销?

如何在 gwt 客户端中设置 Cookie?

如何获取 Chrome 自定义选项卡保存的 cookie?