Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sending cookie with HTTP request in Java

Tags:

java

http

cookies

I'm trying to get a certain cookie in a java client by creating a series of Http requests. It looks like I'm getting a valid cookie from the server but when I'm sending out a request to the fnal url with the seemingly valid cookie I should get some lines of XML in the response but the response is blank because the cookie is wrong or is invalidated because a session has closed or an other problem which I can't figure out. The cookie handed out by the server expires at the end of the session.

It seems to me the cookie is valid because when I do the same calls in Firefox, a similar cookie with the same name and starting with the 3 first same letters and of the same length is stored in firefox, also expiring at the end of the session. If I then make a request to the final url with only this particular cookie stored in firefox (removed all other cookies), the xml is nicely rendered on the page.

Any ideas about what I am doing wrong in this piece of code? One other thing, when I use the value from the very similar cookie generated and stored in Firefox in this piece of code, the last request does give XML feedback in the HTTP response.

// Validate
        url = new URL(URL_VALIDATE);
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("Cookie", cookie);
        conn.connect();

        String headerName = null;
        for (int i = 1; (headerName = conn.getHeaderFieldKey(i)) != null; i++) {
            if (headerName.equals("Set-Cookie")) {
                if (conn.getHeaderField(i).startsWith("JSESSIONID")) {
                    cookie = conn.getHeaderField(i).substring(0, conn.getHeaderField(i).indexOf(";")).trim();
                }
            }
        }

        // Get the XML
        url = new URL(URL_XML_TOTALS);
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("Cookie", cookie);
        conn.connect();

        // Get the response
        StringBuffer answer = new StringBuffer();
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;
        while ((line = reader.readLine()) != null) {
            answer.append(line);
        }
        reader.close();

        //Output the response
        System.out.println(answer.toString())
like image 814
nkr1pt Avatar asked Mar 27 '10 10:03

nkr1pt


1 Answers

I'm feeling a bit too lazy to debug your code, but you might consider letting a CookieHandler do the heavy lifting. Here's one I made earlier:

public class MyCookieHandler extends CookieHandler {
  private final Map<String, List<String>> cookies = 
                                            new HashMap<String, List<String>>();

  @Override public Map<String, List<String>> get(URI uri,
      Map<String, List<String>> requestHeaders) throws IOException {
    Map<String, List<String>> ret = new HashMap<String, List<String>>();
    synchronized (cookies) {
      List<String> store = cookies.get(uri.getHost());
      if (store != null) {
        store = Collections.unmodifiableList(store);
        ret.put("Cookie", store);
      }
    }
    return Collections.unmodifiableMap(ret);
  }

  @Override public void put(URI uri, Map<String, List<String>> responseHeaders)
      throws IOException {
    List<String> newCookies = responseHeaders.get("Set-Cookie");
    if (newCookies != null) {
      synchronized (cookies) {
        List<String> store = cookies.get(uri.getHost());
        if (store == null) {
          store = new ArrayList<String>();
          cookies.put(uri.getHost(), store);
        }
        store.addAll(newCookies);
      }
    }
  }
}

The CookieHandler assumes your cookie handling is global to the JVM; if you want per-thread client sessions or some other more complicated transaction handling, you may be better off sticking with your manual approach.

like image 145
McDowell Avatar answered Sep 19 '22 02:09

McDowell