Sending cookie with HTTP request in Java
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.开发者_StackOverflow中文版close();
//Output the response
System.out.println(answer.toString())
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.
精彩评论