2015-04-26 68 views
0

我可以讓我的代碼以編程方式登錄到任何URL的唯一方法是使用CookieHandler.setDefault(new CookieManager);。這很好,但我想了解每個新的HttpsURLConnection之間的cookie是如何維護的。Java類CookieHandler和CookieManager如何工作?

有人可以展示如何使下面的代碼登錄到Gmail帳戶,而無需使用CookieHandler.setDefault(new CookieManager);?謝謝。

**注意:
- 用您自己的電子郵件和密碼替換。
- CookieHandler.setDefault(new CookieManager);已在下面的代碼中註釋掉。

public class GmailApp { 

    private List<String> cookies; 
    private HttpsURLConnection conn; 

    public static void main(String[] args) throws Exception { 

     String url = "https://accounts.google.com/ServiceLoginAuth"; 
     String gmail = "https://mail.google.com/mail/"; 

     GmailApp http = new GmailApp(); 

     // CookieHandler.setDefault(new CookieManager()); 

     String page = http.GetPageContent(url); 
     String postParams = http.getFormParams(page, "[email protected]", "mypassword"); 
     http.sendPost(url, postParams); 

     String result = http.GetPageContent(gmail); 
     System.out.println(result); 
    } 

    private void sendPost(String url, String postParams) throws Exception { 

     URL obj = new URL(url); 
     conn = (HttpsURLConnection) obj.openConnection(); 
     conn.setDoOutput(true); 
     DataOutputStream wr = new DataOutputStream(conn.getOutputStream()); 
     wr.writeBytes(postParams); 
     wr.flush(); 
     wr.close(); 

     int responseCode = conn.getResponseCode(); 
     System.out.println("\nSending 'POST' request to URL : " + url); 
     System.out.println("Post parameters : " + postParams); 
     System.out.println("Response Code : " + responseCode); 

     BufferedReader in = 
       new BufferedReader(new InputStreamReader(conn.getInputStream())); 
     String inputLine; 
     StringBuffer response = new StringBuffer(); 

     while ((inputLine = in.readLine()) != null) { 
      response.append(inputLine); 
     } 
     in.close(); 
    } 

    private String GetPageContent(String url) throws Exception { 

     URL obj = new URL(url); 
     conn = (HttpsURLConnection) obj.openConnection(); 
     conn.setRequestMethod("GET"); 
     conn.setUseCaches(false); 
     if (cookies != null) { 
      for (String cookie : this.cookies) { 
       conn.addRequestProperty("Cookie", cookie.split(";", 1)[0]); 
      } 
     } 
     int responseCode = conn.getResponseCode(); 
     System.out.println("\nSending 'GET' request to URL : " + url); 
     System.out.println("Response Code : " + responseCode); 

     BufferedReader in = 
       new BufferedReader(new InputStreamReader(conn.getInputStream())); 
     String inputLine; 
     StringBuffer response = new StringBuffer(); 

     while ((inputLine = in.readLine()) != null) { 
      response.append(inputLine); 
     } 
     in.close(); 
     setCookies(conn.getHeaderFields().get("Set-Cookie")); 
     return response.toString(); 
    } 

    public String getFormParams(String html, String username, String password) 
      throws UnsupportedEncodingException { 

     System.out.println("Extracting form's data..."); 

     Document doc = Jsoup.parse(html); 

     Element loginform = doc.getElementById("gaia_loginform"); 
     Elements inputElements = loginform.getElementsByTag("input"); 
     List<String> paramList = new ArrayList<String>(); 
     for (Element inputElement : inputElements) { 
      String key = inputElement.attr("name"); 
      String value = inputElement.attr("value"); 

      if (key.equals("Email")) 
       value = username; 
      else if (key.equals("Passwd")) 
       value = password; 
      paramList.add(key + "=" + URLEncoder.encode(value, "UTF-8")); 
     } 

     StringBuilder result = new StringBuilder(); 
     for (String param : paramList) { 
      if (result.length() == 0) { 
       result.append(param); 
      } else { 
       result.append("&" + param); 
      } 
     } 
     return result.toString(); 
    } 

    public void setCookies(List<String> cookies) { 
     this.cookies = cookies; 
    } 

} 

回答

1

當您設置一個默認CookieHandler靜態通過java.net.CookieHandler.setDefault(),當前和今後HttpURLConnection秒(通過其潛在的HTTP客戶端類)將檢查這個默認的cookie處理程序的存在,並發現它會用它來檢索cookie請求,並存儲設置/返回的新Cookie。只要你想在所有請求中維護cookie,這就提供了一個靜態cookie-jar。一定要設置所需的CookiePolicy,或者java.net.CookiePolicy.ACCEPT_ORIGINAL_SERVER是默認值。

注意有一個與你的代碼的幾個問題:

cookie.split(";", 1)[0] 

這種分裂不會做任何事情,你想cookie.split(";", 2)[0](1-> 2)如果要截斷從第一個分號開始的字符串。

此外,您只需在GET請求後調用setCookies - 您還需要在對POST登錄的響應中捕獲cookie。

+0

我發佈的代碼只是一個示例。我想我應該簡化它。您提到的提及與我的實際問題無關。我只希望有人發佈CookieHandler和CookieManager如何管理Cookie的手動解釋。 – dbconfession

+0

我在'CookieHandler'上添加了一些細節。 – javabrett

+1

謝謝佈雷特。我想最終,我希望能夠跨連接登錄和維護一個cookie,而不需要使用'CookieHandler',這樣我就能從根本上理解它在做什麼。無論我做什麼,即使我將響應cookie存儲到變量並設置下一個請求,以使用'.setRequestProperty(「Cookie」,loginCookie)''使用該cookie,每個連接似乎都會失敗。您能否演示如何手動處理響應cookie並在下一個請求中有效使用它? – dbconfession