当前位置: 首页 > 面试题库 >

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

殳勇
2023-03-14
问题内容

我有一个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时,该servlet都会成功增加一个计数器。可以在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并随请求重新发送它们?


问题答案:

我运行您的代码并将其替换

CookieHandler.setDefault(new CookieManager());

通过

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

这行得通!



 类似资料:
  • 我有一个Java应用程序(JDK 1.7.0_13),正在使用java.net.HttpURLConnection连接到一些基于servlet的服务,这些服务进行会话管理。我试图弄清楚如何使用java.net.CookieManager来跟踪会话cookie。阅读文档我得到的印象是,使用CookieHandler.setDefault(new CookieManager())安装CookieMan

  • 今天我在skype上面试了一份PHP开发人员的工作,其中一个问题是关于Cookie和PHP会话。 问题是,如果用户浏览器中禁用Cookies,可以设置和读取、使用PHP会话吗? 我告诉他们不要,因为PHP会话默认取决于设置会话cookie。当PHP会话启动时,新的会话Cookie被设置为默认名称PHPSESSID,并且该Cookie保存该会话id的值,例如:ftu63d8al491s5gatuob

  • null 有人知道解决这个问题的办法吗?提前感谢! 迈克尔

  • 问题内容: 有什么方法可以保证应用程序不会在Oracle中释放行锁吗?如果我确保将commit语句放在finally块中,则可以处理意外错误的情况,但是如果应用程序进程在提交前突然中断(或者有人将电源线/局域网电缆拔出),该怎么办。 有没有办法让Oracle在X时间后自动回滚空闲会话?还是在我以某种方式检测到连接丢失时回滚? 根据我所做的实验,如果我在提交某个应用程序进程之前终止了该进程,则行锁将

  • 问题内容: 假设我们在Python 3.x中(我猜在Python 2.6和Python 2.7中也)具有以下功能: 如果运行它们,我们将得到: 这三个函数提供相同的结果(值和类型),它们似乎是等效的。 但是,其中哪个陈述更正确? 这些定义中是否有副作用? 相同的问题适用于以下情况,并返回了多个值: 在这种情况下,每个函数都返回一个 元组 ,但是我的问题仍然保持不变。 问题答案: Python中的括

  • 问题内容: 我有一个表,该表具有指向两个不同表的两个外键,两个外键 共享一个列 : 如您所见,有两个FK共享country_code(恰好在引用路径的末尾引用同一列)。实体类看起来像(JPA 1.0 @IdClass): 如您所见,我将countryCode属性和城市的country_code @JoinColumn标记为只读(insertable = false,可更新= false)。Hibe