snapplex
snapplex

Reputation: 851

Cookie management with Java URLConnection

I'm fairly new to android programming and recently achieved a successful HTTP Post request, only to learn that my cookies are not being stored between subsequent Post/Get requests. I looked around the interweb, and found a few examples for Android's Apache client and Java's HttpURLConnection. I was unsuccessful in implementing either method into my current class, so I was wondering if someone with more experience could review my code and offer suggestions.

Recap:

  1. My initial POST request is successful and authenticated.
  2. My second POST request does not retain the cookies from the initial POST request.
  3. Is there any specific instance or reason why someone might opt for the Apache method or the Java implementation? Are both equals in their own right or does one offer more capabilities and flexibility than the other?

Any help is appreciated, thank you.

webCreate.java

import android.util.Log;

import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.CookieHandler;
import java.net.CookieManager;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
import java.net.URL;

import javax.net.ssl.HttpsURLConnection;

public class webCreate {

    private final String USER_AGENT = "Mozilla/5.0";


    // HTTP GET request
    public void sendGet(String url) throws Exception {

        CookieManager cookieManager = new CookieManager();
        CookieHandler.setDefault(cookieManager);
        HttpCookie cookie = new HttpCookie("lang", "en");


        URL obj = new URL(url);
        HttpURLConnection con = (HttpURLConnection) obj.openConnection();

        // optional default is GET
        con.setRequestMethod("GET");

        //add request header
        con.setRequestProperty("User-Agent", USER_AGENT);

        int responseCode = con.getResponseCode();
        Log.d("sendGet", "\nSending 'GET' request to URL : " + url);


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


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

        in.close();

        //print result
        System.out.println(response.toString());
        Log.d("Response Code", response.toString());
    }

    // HTTP POST request
    String  sendPost(String url, String urlParams) throws Exception {

        CookieManager cookieManager = new CookieManager();
        CookieHandler.setDefault(cookieManager);
        HttpCookie cookie = new HttpCookie("lang", "en");

        URL obj = new URL(url);
        HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

        //add request header
        con.setRequestMethod("POST");
        con.setRequestProperty("User-Agent", USER_AGENT);
        con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");

        // Send post request
        con.setDoOutput(true);
        DataOutputStream wr = new DataOutputStream(con.getOutputStream());
        wr.writeBytes(urlParams);
        wr.flush();
        wr.close();

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

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

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

        System.out.println("Response Code : " + response);
        return  response.toString();
    }

}

Upvotes: 2

Views: 5905

Answers (1)

MCToon
MCToon

Reputation: 668

You need to maintain your cookie context external to each call and provide the same cookie store it on subsequent GETs and POSTs. This is the same for both the Java implementation and Apache's implementation.

In my experience, Apache's HTTP components is better than the built in Java implementation. I spent a large amount of time trying to write a utility using Java's implementation, my largest problem was timeouts. Bad web servers would hang causing the connection to hang indefinitely. After switching to Apache the timeouts were tuneable and we didn't have any more hung threads.


I'll give an example using Apache.

Create the CookieStore instance in your parent method:

CookieStore cookieStore = new BasicCookieStore();

Then in your GET or POST implementations pass in the CookieStore instance and use it when you build the HttpClient:

public void sendGet(String url, CookieStore cookieStore) throws Exception {
    ...
    HttpClient client = HttpClientBuilder.create().setDefaultCookieStore(cookieStore).build();

    HttpGet request = new HttpGet(uri);  // or HttpPost...
    request.addHeader("User-Agent", USER_AGENT);
    HttpResponse response = client.execute(request);

    BufferedReader br = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
    ...
}

Android has extended java.net.HttpURLConnection and recommends using this, so I'll also give an outline for that as well.

HttpURLConnection and HttpsURLConnection automatically and transparently uses the CookieManager set in CookieHandler. CookieHandler is VM-wide so must be setup only once. If you create a new CookieManager for each request, as you did in your code, it will wipe out any cookies set in previous requests.

You do not need to create an instance of HttpCookie yourself. When HttpURLConnection receives a cookie from the server the CookieManager will receive the cookie and store it. Future requests to the same server will automatically send the previously set cookies.

So, move this code to your application setup so it happens only once:

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

Upvotes: 6

Related Questions