日期:2014-05-16  浏览次数:20399 次

不同工具(jsoup、httpclient)获取多个同路径下同名Cookie的问题

这两天在iteye的问答中有一个【java中使用jsoup获取cookies】问题, 地址:http://www.iteye.com/problems/87415。

?

不知大家遇到类似的问题吗,希望一起探讨。


1、首先第一次访问http://www.17sct.com/city.php?ename=CHANGZHOU,我们可以看到如下请求:


我们看到 设置了两个 99a0_city cookie, 值分别为1 和 269;如chrome、firefox、ie8将选择最后一个作为cookie值。

?

好像没什么问题,接下来继续看两个工具:

1、jsoup

?

        Connection conn = Jsoup.connect("http://www.17sct.com/city.php?name=CHANGZHOU");
    	conn.method(Method.GET);
    	conn.followRedirects(false);
    	Response response = conn.execute();
    	System.out.println(response.cookies());
    	//{referer=deleted, 99a0_city=1, PHPSESSID=b5rjkoq2s2qmukjf9n2ffvjvn5}
    	//立即过期的也显示出了,即从服务器传过来的都显示

?

? 99a0_city竟然为1,即选择了第一个作为cookie的值。

?

查看并修改org.jsoup.helper.HttpConnection中获取cookie的代码:

?

            // headers into map
            Map<String, List<String>> resHeaders = conn.getHeaderFields();
            
            for (Map.Entry<String, List<String>> entry : resHeaders.entrySet()) {
                String name = entry.getKey();
                if (name == null)
                    continue; // http/1.1 line

                List<String> values = entry.getValue();

                if (name.equalsIgnoreCase("Set-Cookie")) {
                    for (String value : values) {
                        TokenQueue cd = new TokenQueue(value);
                        String cookieName = cd.chompTo("=").trim();
                        String cookieVal = cd.consumeTo(";").trim();
                        // ignores path, date, domain, secure et al. req'd?
                        System.out.println(cookieName+"="+cookieVal);
                        cookie(cookieName, cookieVal);
                    }
                } else { // only take the first instance of each header
                    if (!values.isEmpty())
                        header(name, values.get(0));
                }
            }

?

?

conn是java.net.HttpURLConnection,也就是说如果使用HttpURLConnection时 有多个同名的cookie 将获取第一个作为cookie的值。

?

2、HttpClient,和浏览器行为一样获取最后一个Cookie:

?

    	HttpClient client = new HttpClient();
    	GetMethod get = new GetMethod("http://www.17sct.com/city.php?ename=CHANGZHOU");
    	get.setFollowRedirects(false);
    	client.executeMethod(get);
    	System.out.println(Arrays.toString(client.getState().getCookies()));
    	//[PHPSESSID=cn74fv516879pv26h5lbaf9gd0, 99a0_city=269]
    	//立即过期的不显示出来
?

?

?

因此总结:

1、使用java.net.HttpURLConnection的工具/框架,如果多个同路径下同名的cookie将获取第一个

2、使用apache?HttpClient,和浏览器行为一样获取最后一个。

?

?

因此,当我们在使用cookie时,尽量保证服务器设置一个cookie。

?

?

还要注意:

?

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

2、使用apache?HttpClient,不会获取到过期的cookie。

?

不知大家遇到类似的问题吗,希望一起探讨。

1 楼 snowolf 2012-08-22  
是个问题。。。。。
2 楼 jinnianshilongnian 2012-08-22  
snowolf 写道
是个问题。。。。。

嗯  今天在问答频道解答遇到的 很细节。。。。
3 楼 飞天奔月 2012-08-27  
对jsoup 也有研究啊

我jsoup  没有用过 cookie

4 楼 jinnianshilongnian 2012-08-27