1. 程式人生 > >不同工具(jsoup、httpclient)獲取多個同路徑下同名Cookie的問題

不同工具(jsoup、httpclient)獲取多個同路徑下同名Cookie的問題

不知大家遇到類似的問題嗎,希望一起探討。


1、首先第一次訪問http://www.17sct.com/city.php?ename=CHANGZHOU,我們可以看到如下請求:


我們看到 設定了兩個 99a0_city cookie, 值分別為1 和 269;如chrome、firefox、ie8將選擇最後一個作為cookie值。

好像沒什麼問題,接下來繼續看兩個工具:

1、jsoup

Java程式碼  收藏程式碼
  1.    Connection conn = Jsoup.connect("http://www.17sct.com/city.php?name=CHANGZHOU");  
  2. conn.method(Method.GET);  
  3. conn.followRedirects(false);  
  4. Response response = conn.execute();  
  5. System.out.println(response.cookies());  
  6. //{referer=deleted, 99a0_city=1, PHPSESSID=b5rjkoq2s2qmukjf9n2ffvjvn5}
  7. //立即過期的也顯示出了,即從伺服器傳過來的都顯示

  99a0_city竟然為1,即選擇了第一個作為cookie的值。

檢視並修改org.jsoup.helper.HttpConnection中獲取cookie的程式碼:

Java程式碼  收藏程式碼
  1. // headers into map
  2. Map<String, List<String>> resHeaders = conn.getHeaderFields();  
  3. for (Map.Entry<String, List<String>> entry : resHeaders.entrySet()) {  
  4.     String name = entry.getKey();  
  5.     if (name == null)  
  6.         continue// http/1.1 line
  7.     List<String> values = entry.getValue();  
  8.     if
     (name.equalsIgnoreCase("Set-Cookie")) {  
  9.         for (String value : values) {  
  10.             TokenQueue cd = new TokenQueue(value);  
  11.             String cookieName = cd.chompTo("=").trim();  
  12.             String cookieVal = cd.consumeTo(";").trim();  
  13.             // ignores path, date, domain, secure et al. req'd?
  14.             System.out.println(cookieName+"="+cookieVal);  
  15.             cookie(cookieName, cookieVal);  
  16.         }  
  17.     } else { // only take the first instance of each header
  18.         if (!values.isEmpty())  
  19.             header(name, values.get(0));  
  20.     }  
  21. }  

conn是java.net.HttpURLConnection,也就是說如果使用HttpURLConnection時 有多個同名的cookie 將獲取第一個作為cookie的值。

2、HttpClient,和瀏覽器行為一樣獲取最後一個Cookie:

Java程式碼  收藏程式碼
  1. HttpClient client = new HttpClient();  
  2. GetMethod get = new GetMethod("http://www.17sct.com/city.php?ename=CHANGZHOU");  
  3. get.setFollowRedirects(false);  
  4. client.executeMethod(get);  
  5. System.out.println(Arrays.toString(client.getState().getCookies()));  
  6. //[PHPSESSID=cn74fv516879pv26h5lbaf9gd0, 99a0_city=269]
  7. //立即過期的不顯示出來
 

因此總結:

1、使用java.net.HttpURLConnection的工具/框架,如果多個同路徑下同名的cookie將獲取第一個

2、使用apache HttpClient,和瀏覽器行為一樣獲取最後一個。

因此,當我們在使用cookie時,儘量保證伺服器設定一個cookie。

還要注意:

1、使用java.net.HttpURLConnection的工具/框架,可能獲取到過期的cookie,如之前的referer[過期時間是2011年,即立即過期];

2、使用apache HttpClient,不會獲取到過期的cookie。