HttpURLConnection 中Cookie 使用

如果想通過 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信息。


想了解更多精彩內容請關注我的公眾號

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,991評論 19 139
  • 一說到REST,我想大家的第一反應就是“啊,就是那種前后臺通信方式。”但是在要求詳細講述它所提出的各個約束,以及如...
    時待吾閱讀 3,477評論 0 19
  • HTTP cookie(也稱為web cookie,網絡cookie,瀏覽器cookie或者簡稱cookie)是網...
    留七七閱讀 18,124評論 2 71
  • API定義規范 本規范設計基于如下使用場景: 請求頻率不是非常高:如果產品的使用周期內請求頻率非常高,建議使用雙通...
    有涯逐無涯閱讀 2,607評論 0 6
  • 愿你自由自在,只按照自己的方式生活。 說實話,最新一期的《中國有嘻哈》是沖著吳亦凡和王嘉爾去看的。雖然是如此,但我...
    木可爾閱讀 1,890評論 1 2