HttpURLConnection 中Cookie 使用

作者: jijs | 来源:发表于2017-08-10 22:39 被阅读503次

    如果想通过 HttpURLConnection 访问网站,网站返回cookie信息,下次再通过HttpURLConnection访问时,把网站返回 cookie信息再返回给该网站。可以使用下面代码。

    CookieManager manager = new CookieManager();
    CookieHandler.setDefault(manager);
    

    通过这两行代码就可以把网站返回的cookie信息存储起来,下次访问网站的时候,自动帮你把cookie信息带上。

    CookieManager还可以设置CookiePolicy。设置如下:

    CookieManager manager = new CookieManager();
    //设置cookie策略,只接受与你对话服务器的cookie,而不接收Internet上其它服务器发送的cookie
    manager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
    

    有关CookiePolicy请详看: CookiePolicy 原理解析

    CookieHandler 源码分析

    public abstract class CookieHandler {
    
        private static CookieHandler cookieHandler;
    
        public synchronized static CookieHandler getDefault() {
            SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                sm.checkPermission(SecurityConstants.GET_COOKIEHANDLER_PERMISSION);
            }
            return cookieHandler;
        }
       
        public synchronized static void setDefault(CookieHandler cHandler) {
            SecurityManager sm = System.getSecurityManager();
            if (sm != null) {
                sm.checkPermission(SecurityConstants.SET_COOKIEHANDLER_PERMISSION);
            }
            cookieHandler = cHandler;
        }
        
        public abstract Map<String, List<String>>
            get(URI uri, Map<String, List<String>> requestHeaders)
            throws IOException;
    
        public abstract void
            put(URI uri, Map<String, List<String>> responseHeaders)
            throws IOException;
    }
    

    CookieHandler是抽象类,内部提供了静态的setDefault方法。
    并且 private static CookieHandler cookieHandler; 是静态的。
    子类需要实现get()和put()方法。
    get()方法返回该uri相关的cookie。
    put()方法是存储该uri相关的cookie。

    jdk1.6中提供了CookieHandler的实现类CookieManager。

    CookieManager 源码分析

    get()方法

    Paste_Image.png

    CookieManager.get() 方法实现了从CookieStore中获取该uri对应的cookie。

    put() 方法

    Paste_Image.png

    首先解析http 相应头信息中的cookie,并存储到 List<HttpCookie> cookies 中。

    Paste_Image.png

    循环cookies中的cookie,根据设置的CookiePolicy来判断是否接收该Cookie信息,
    如果接收则存储到CookieStore。

    Cookie实现机制

    这样每次在调用HttpURLConnection访问网站的时候,通过CookieHandler.getDefault()方法获取CookieManager实例(静态的方法,全局都可用)。
    从解析http的响应头中的cookie调用CookieHandler中的put方法存放到CookieStore中。
    再次访问网站的时候调用CookieHandler中的get方法获取该uri响应的cookie,并提交到该站点中。
    这样开发人员就不需要干预cookie信息,则每次访问网站会自动携带cookie。

    代码示例

    本例子中使用到了CookieHandler、CookieManager 、CookieStore、 HttpCookie。

    public class CookieManagerDemo {
    
        //打印cookie信息
        public static void printCookie(CookieStore cookieStore){
            List<HttpCookie> listCookie = cookieStore.getCookies();
            listCookie.forEach(httpCookie -> {
                System.out.println("--------------------------------------");
                System.out.println("class      : "+httpCookie.getClass());
                System.out.println("comment    : "+httpCookie.getComment());
                System.out.println("commentURL : "+httpCookie.getCommentURL());
                System.out.println("discard    : "+httpCookie.getDiscard());
                System.out.println("domain     : "+httpCookie.getDomain());
                System.out.println("maxAge     : "+httpCookie.getMaxAge());
                System.out.println("name       : "+httpCookie.getName());
                System.out.println("path       : "+httpCookie.getPath());
                System.out.println("portlist   : "+httpCookie.getPortlist());
                System.out.println("secure     : "+httpCookie.getSecure());
                System.out.println("value      : "+httpCookie.getValue());
                System.out.println("version    : "+httpCookie.getVersion());
                System.out.println("httpCookie : "+httpCookie);
            });
        }
    
        public static void requestURL() throws Exception{
            URL url = new URL("http://192.168.3.249:9000/webDemo/index.jsp");
            HttpURLConnection conn = (HttpURLConnection)url.openConnection();
            String basic = Base64.getEncoder().encodeToString("infcn:123456".getBytes());
            conn.setRequestProperty("Proxy-authorization", "Basic " + basic);
            BufferedReader br = new BufferedReader(new InputStreamReader(conn.getInputStream()));
            String line = null;
            while((line=br.readLine())!=null){
                System.out.println(line);
            }
            br.close();
        }
    
        public static void main(String[] args) throws Exception {
            
            CookieManager manager = new CookieManager();
            //设置cookie策略,只接受与你对话服务器的cookie,而不接收Internet上其它服务器发送的cookie
            manager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
            CookieHandler.setDefault(manager);
            
            printCookie(manager.getCookieStore());
            //第一次请求
            requestURL();
    
            printCookie(manager.getCookieStore());
            //第二次请求
            requestURL();
        }
        
    }
    
    Paste_Image.png

    从抓包结果中发现,第二次访问该站点的时候,会自动携带Cookie信息。


    想了解更多精彩内容请关注我的公众号

    相关文章

      网友评论

        本文标题:HttpURLConnection 中Cookie 使用

        本文链接:https://www.haomeiwen.com/subject/amuqrxtx.html