Why doesn't HttpClient work but HttpUrlConnenction do when posting data to form
I'm building an android app which should perform a GET on my site to get two cookies and then perform a post to the same site with these cookies.
As mentioned I start of with the GET and I'm using org.apache.http.client.HttpClient to perform this operation.
String requiredCookies = "";
HttpContext localContext = null;
System.out.println("------------------GET----------------------");
HttpClient httpClient = new DefaultHttpClient();
HttpGet get = new HttpGet("www.mysitegeturl.com");
//Creating a local instance of cookie store.
CookieStore cookieJar = new BasicCookieStore();
// Creating a local HTTP context
localContext = new BasicHttpContext();
// Bind custom cookie store to the local context
localContext.setAttribute(ClientContext.COOKIE_STORE, cookieJar);
HttpResponse response;
try {
response = httpClient.execute(get, localContext);
HttpEntity entity = response.getEntity();
System.out.println(response.getStatusLine());
if (entity != null) {
System.out.println("Response content length: " + entity.getContentLength());
}
//Do this so that Java.net impl should work
List<Cookie> cookies = cookieJar.getCookies();
for (int i = 0; i < cookies.size(); i++) {
requiredCookies += cookies.get(i).getName()+"="+cookies.get(i).getValue()+";";
}
if (entity != null) {
entity.consumeContent();
}
} catch (ClientProtocolException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
System.out.println("------------------GET-END---------------------");
So far so good. Don't mind the requiredCookies line yet, it will be used in the Java.net impl since I can't get the HttpClient one to work =(. Let's take a look at the non working HttpClient Post part.
System.out.println("------------------HttpClient - POST----------------------");
HttpPost post = new HttpPost("www.mysiteposturl.com");
//Params
HttpParams params = new BasicHttpParams();
params.setParameter("foo", "post");
params.setParameter("bar", "90");
params.setParameter("action", "search");
post.setParams(params);
post.setHeader("Co开发者_如何转开发ntent-Type", "application/x-www-form-urlencoded");
try {
HttpResponse response2 = httpClient.execute(post, localContext);
System.out.println(response2.getStatusLine());
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("------------------POST END---------------------");
What happens now is that I perform a POST with the localContext where the cookies are stored. This doesn't work. I get a HTTP/1.1 401 No session. Since I had no luck with this I tried another approach(java.net.HttpURLConnection). Remember I still use the same GET part
URL url = new URL("www.mysiteposturl");
HttpURLConnection connection = null;
String dataString = "bar=90&foo=post&action=search";
try {
connection = (HttpURLConnection)url.openConnection();
connection.setRequestProperty("Cookie", requiredCookies);
//Set to POST
connection.setDoOutput(true);
Writer writer = new OutputStreamWriter(connection.getOutputStream());
writer.write(dataString);
writer.flush();
writer.close();
connection.connect();
if (connection.getResponseCode() == 200 || connection.getResponseCode() == 201) {
System.out.println(connection.getContent().toString());
} else {
System.out.println("Error");
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("------------------POST END---------------------");
And VIOLA a 200 is displayed and everything works like a charm. What do you guys think? Could someone please provide me with an answer because I can't figure it out.
The problem appears to be that you have two different host names in the setup. This will cause HTTP Client to not send cookies for a different host. You could try changing the domain of the cookies in the cookie store, or using the same host for GET and POST. Additionally you could manually add the cookies to the headers in HTTP Client as you did in the HttpURLConnection example.
I guess it was a mistake that you used two completely different domains for your two requests — i.e. you were trying to mask your real URL? If not, then that's why you're not getting any cookies. If were just trying to mask your URL, well that's why example.com exists. :)
Alternatively, and this is completely off the top of my head from code I wrote last week — it worked fine across multiple GETs, POSTs and subdomains:
DefaultHttpClient httpClient = new DefaultHttpClient();
CookieStore cookieJar = new BasicCookieStore();
httpClient.setCookieStore(cookieJar);
i.e. I'm explicitly using a DefaultHttpClient
, which I believe has those extra get/setters for the cookie store. I don't think I used any context objects either.
精彩评论