如果想通過 HttpURLConnection 訪問網站,網站返回cookie信息,下次再通過HttpURLConnection訪問時,把網站返回 cookie信息再返回給該網站??梢允褂孟旅娲a。
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()方法
CookieManager.get() 方法實現了從CookieStore中獲取該uri對應的cookie。
put() 方法
首先解析http 相應頭信息中的cookie,并存儲到 List<HttpCookie> cookies 中。
循環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();
}
}
從抓包結果中發現,第二次訪問該站點的時候,會自動攜帶Cookie信息。
想了解更多精彩內容請關注我的公眾號