dbconfession
dbconfession

Reputation: 1199

How do the Java classes CookieHandler and CookieManager work?

The only way I can get my code to programmatically login to any URL is by using CookieHandler.setDefault(new CookieManager);. Which is fine, but I want to understand how the cookie is being maintained between each new HttpsURLConnection.

Can someone please show how to make the code below log into a gmail account without having to use CookieHandler.setDefault(new CookieManager);? Thanks.

**NOTES:
- substitute with your own email and password.
-CookieHandler.setDefault(new CookieManager); is commented out in the code below.

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;
    }

} 

Upvotes: 1

Views: 5307

Answers (1)

javabrett
javabrett

Reputation: 7618

When you set a default CookieHandler statically via java.net.CookieHandler.setDefault(), current and future HttpURLConnections (via their underlying HTTP client classes) will check for the existence of this default cookie handler, and finding it will use it to retrieve cookies for requests, and store new cookies set/returned. This provides a static cookie-jar for as long as you want to maintain cookies across all requests. Be sure to set the desired CookiePolicy, or java.net.CookiePolicy.ACCEPT_ORIGINAL_SERVER is the default.

Note there's a few issues with your code:

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

This split won't do anything, you want cookie.split(";", 2)[0] (1->2) if you want to truncate the string from the first semicolon onwards.

Also, you are only calling setCookies after your GET requests - you also need to capture the cookies in the response to the POST login.

Upvotes: 1

Related Questions