2013-02-13 52 views
24

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

为了测试事情,我有一个servlet,每当我的浏览器访问一个URL时,就会成功递增一个计数器。这在Safari,FireFox和Chrome中运行良好......但是,我无法从独立的Java应用程序中使用它。

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

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和其他与请求重发呢?

+0

请移动到http://stackoverflow.com/questions/12349266/how-do-i-persist-cookies-when-using-httpurlconnection/32001630#32001630。最好的解决方案已经出现 – hgg 2015-08-14 03:14:39

回答

55

我运行代码,并替换该

CookieHandler.setDefault(new CookieManager()); 

通过

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

它的工作!

+1

谢谢。精彩的工作。当然,现在我知道答案,文档很容易找到。 ;-) – Chuck 2013-03-24 15:00:07

+1

这是一个不错的,更紧凑的答案,你可以找到。谢谢! – Panayotis 2014-02-23 20:18:02