httpclient redirect for newbies [duplicate] - java

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Httpclient 4, error 302. How to redirect?
I want to retrieve some information from my comcast account. Using examples on this site, I think I got pretty close. I am using firebug to see what to post, and I see that when I login I am being redirected. I don't understand how to follow the redirects. I have played with countless examples but just can't figure it out. I am new to programming and just not having any luck doing this. Here is my code. I make an initial login, then go to try to go to another URL which is where the redirects begin. Along the way, I see that I am acquiring lots of cookies, but not the important one s_lst.
HttpPost httpPost = new HttpPost("https://login.comcast.net/login");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("continue", "https://login.comcast.net/account"));
nvps.add(new BasicNameValuePair("deviceAuthn", "false"));
nvps.add(new BasicNameValuePair("forceAuthn", "true"));
nvps.add(new BasicNameValuePair("ipAddrAuthn", "false"));
nvps.add(new BasicNameValuePair("lang", "en"));
nvps.add(new BasicNameValuePair("passwd", "mypassword"));
nvps.add(new BasicNameValuePair("r", "comcast.net"));
nvps.add(new BasicNameValuePair("rm", "2"));
nvps.add(new BasicNameValuePair("s", "ccentral-cima"));
nvps.add(new BasicNameValuePair("user", "me"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
System.out.println("executing request " + httpPost.getURI());
// Create a response handler
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httpPost, responseHandler);
String cima = StringUtils.substringBetween(responseBody, "cima.ticket\" value=\"", "\">");
System.out.println(cima);
HttpPost httpPost2 = new HttpPost("https://customer.comcast.com/Secure/Home.aspx");
List <NameValuePair> nvps2 = new ArrayList <NameValuePair>();
nvps2.add(new BasicNameValuePair("cima.ticket", cima));
httpPost2.setEntity(new UrlEncodedFormEntity(nvps2, HTTP.UTF_8));
System.out.println("executing request " + httpPost2.getURI());
// Create a response handler
ResponseHandler<String> responseHandler2 = new BasicResponseHandler();
String responseBody2 = httpclient.execute(httpPost2, responseHandler2);
System.out.println(responseBody2);

Here's a sample adapted from the 'Response Handling' example here.
Your example is quite complicated - best to simplify your code while you figure out how to follow redirects (you can comment out the section I've highlighted to show the example failing to follow the redirect).
import org.apache.http.*;
import org.apache.http.client.*;
import org.apache.http.client.methods.*;
import org.apache.http.impl.client.*;
import org.apache.http.protocol.*;
public class ClientWithResponseHandler {
public final static void main(String[] args) throws Exception {
DefaultHttpClient httpclient = new DefaultHttpClient();
// Comment out from here (Using /* and */)...
httpclient.setRedirectStrategy(new DefaultRedirectStrategy() {
public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context) {
boolean isRedirect=false;
try {
isRedirect = super.isRedirected(request, response, context);
} catch (ProtocolException e) {
e.printStackTrace();
}
if (!isRedirect) {
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == 301 || responseCode == 302) {
return true;
}
}
return false;
}
});
// ...to here and the request will fail with "HttpResponseException: Moved Permanently"
try {
HttpPost httpPost = new HttpPost("http://news.bbc.co.uk/");
System.out.println("executing request " + httpPost.getURI());
// Create a response handler
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String responseBody = httpclient.execute(httpPost, responseHandler);
System.out.println(responseBody);
// Add your code here...
} finally {
// When HttpClient instance is no longer needed, shut down the connection
// manager to ensure immediate deallocation of all system resources
httpclient.getConnectionManager().shutdown();
}
}
}

Related

Passing parameters in integration test JAVA

I try to pass parameters in post request in integration test, but I get response that required parameter "source" aint detected. Maybe you will know what is cause. Thank you.
public void testUploadBundleFromRepository() throws IOException, InterruptedException {
String boundary = "---------------"+ UUID.randomUUID().toString();
String uri = String.format("http://%s:%d/upload/", HOST, PORT);
HttpPost httpPost = new HttpPost(uri);
httpPost.setHeader(HTTP.CONTENT_TYPE, ContentType.MULTIPART_FORM_DATA.getMimeType()+";boundary="+boundary);
List<NameValuePair> postParameters = new ArrayList<>();
postParameters.add(new BasicNameValuePair("source","repo"));
postParameters.add(new BasicNameValuePair("id","1"));
postParameters.add(new BasicNameValuePair("start", "true"));
httpPost.setEntity(new UrlEncodedFormEntity(postParameters, "UTF-8"));
HttpResponse response = getHttpClient().execute(httpPost);
//assert in future
}
I think you should call setRequestBody not setEntity
httpPost.setRequestBody(postParameters);

Why does converting this Python POST request to Java not work?

I'm trying to convert this Python code using the Python Requests HTTP library into Java code (for Android).
import requests
payload = {"attr[val1]":123,
"attr[val2]":456,
"time":0,
"name":"Foo","surname":"Bar"}
r = requests.post("http://jakiro.herokuapp.com/api", data=payload)
r.status_code
r.text
This is what I've done so far:
protected void sendJson() {
Thread t = new Thread() {
public void run() {
Looper.prepare(); //For Preparing Message Pool for the child Thread
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); //Timeout Limit
HttpResponse response;
JSONObject json = new JSONObject();
try {
Log.v("SOMETHING_NAME3", "Creating POST");
HttpPost post = new HttpPost("http://jakiro.herokuapp.com/api");
json.put(MessageAttribute.SURNAME, "Bar");
json.put(MessageAttribute.VAL1, 123);
json.put(MessageAttribute.VAL2, 456);
json.put(MessageAttribute.name, "Foo");
json.put(MessageAttribute.TIME, 0);
StringEntity se = new StringEntity( json.toString() );
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
response = client.execute(post);
/*Checking response */
if(response!=null){
InputStream in = response.getEntity().getContent(); //Get the data in the entity
String foo = convertStreamToString(in);
Log.v("SOMETHING_NAME2", foo); // Gives me "Bad request"
}
} catch(Exception e) {
e.printStackTrace();
Log.v("SOMETHING_NAME", "Cannot Establish Connection");
}
Looper.loop(); //Loop in the message queue
}
};
t.start();
}
I've checked the response with response.getStatusLine().getStatusCode() and I get back a 400 from the server. The Python code works fine, but in Java on an Android device it doesn't. I can't see to figure out why though.
#Blender's link was the correct solution at the link: How to use parameters with HttpPost
The correct way to url-encode was to create BasicNameValuePairs and encode that as such:
postParameters = new ArrayList<NameValuePair>();
postParameters.add(new BasicNameValuePair("param1", "param1_value"));
postParameters.add(new BasicNameValuePair("param2", "param2_value"));
httppost.setEntity(new UrlEncodedFormEntity(postParameters));

Following redirects in HTTPResponse Android

I need to follow redirects given to me by HTTPost. When I make an HTTPost, and try to read the response, I get the redirect's page html. How can I fix this? Code:
public void parseDoc() {
final HttpParams params = new BasicHttpParams();
HttpClientParams.setRedirecting(params, true);
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(
"https://secure.groupfusion.net/processlogin.php");
String HTML = "";
try {
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
nameValuePairs.add(new BasicNameValuePair("referral_page",
"/modules/gradebook/ui/gradebook.phtml?type=student_view"));
nameValuePairs.add(new BasicNameValuePair("currDomain",
"beardenhs.knoxschools.org"));
nameValuePairs.add(new BasicNameValuePair("username", username
.getText().toString()));
nameValuePairs.add(new BasicNameValuePair("password", password
.getText().toString()));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
String g = httppost.getURI().toString();
HttpResponse response = httpclient.execute(httppost);
HTML = EntityUtils.toString(response.getEntity());
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String ResponseBody = httpclient.execute(httppost, responseHandler);
sting.setText(HTML);
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
}
When a server sends a redirect, it is actually sending a 3xx response code (usually 301 or 302) that indicates the redirect, and a Location header that tells you the new location.
So, in your case, you can get the Location header from the HttpResponse object and use that to send another request to retrieve the actual content after you've logged in. For example:
String newUrl = response.getFirstHeader("Location").getValue();
So long as you reuse the same HttpClient object for both requests, it should use any cookies set by the login request in your subsequent request(s).
Try using the HttpGet method
GetMethods will follow redirect requests from the http server by default. This behavour can be disabled by calling setFollowRedirects(false).
For more info refer this
Hope it helps,
Cheers

apache httppost how to set content : which have name value pair pointing to another set of name value pair

For example if we need to send content which is in this format , how do we do it
{"name1":[{"name11":"value11"},{"name11":"value12"},{"name11":"value13"}],"name2":value2}
I know how to set the basic kind
{"name1":"value1","name2":value2}
NameValuePair[] nameValuePairs = new NameValuePair[2];
nameValuePairs[0]= new BasicNameValuePair("name1", "value1");
nameValuePairs[1] = new BasicNameValuePair("name2", value2);
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
How can we achieve nesting
Please see this question as it has a couple of answers that should help you. Here is a brief snippet from the answers code:
HttpPost request = new HttpPost(serverUrl);
request.setEntity(new ByteArrayEntity(
postMessage.toString().getBytes("UTF8")));
HttpResponse response = client.execute(request);
The other answer says you can do something like this:
protected void sendJson(final String email, final String pwd) {
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); //Timeout Limit
HttpResponse response;
JSONObject json = new JSONObject();
try{
HttpPost post = new HttpPost(URL);
json.put("email", email);
json.put("password", pwd);
StringEntity se = new StringEntity( "JSON: " + json.toString());
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
response = client.execute(post);
/*Checking response */
if(response!=null){
InputStream in = response.getEntity().getContent(); //Get the data in the entity
}
catch(Exception e){
e.printStackTrace();
createDialog("Error", "Cannot Estabilish Connection");
}
}

How can I post in Android?

I was using Android API, to send some data using http POST method:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://myapp.com/");
try {
List parameters = prepareHttpParameters();
HttpEntity entity = new UrlEncodedFormEntity(parameters);
httppost.setEntity(entity);
ResponseHandler responseHandler = new BasicResponseHandler();
response = httpclient.execute(httppost, responseHandler);
Toast.makeText(this, response, Toast.LENGTH_LONG).show();
} catch (IOException e) {
// TODO: manage ClientProtocolException and IOException
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
}
and my parameters are prepared here:
List parameters = new ArrayList(2);
parameters.add(new BasicNameValuePair("usr", "foo" ));
parameters.add(new BasicNameValuePair("pwd", "bar" ));
return parameters;
But it seems to be wrong because I do not get any expected response.
I have tested the same request with same parameters using Curl and I get expected response.
Am I wrong with my code?
Thank you very much
I'd consider the UrlEncodedFormEntity constructor that takes an encoding as the second parameter. Otherwise, off the cuff, this looks OK. You might check on your server logs what you are receiving for these requests. You might also make sure your emulator has Internet connectivity (i.e., has two bars of signal strength), if you are using the emulator.
Here is the relevant portion of a sample app that uses HTTP POST (and a custom header) to update a user's status on identi.ca:
private String getCredentials() {
String u=user.getText().toString();
String p=password.getText().toString();
return(Base64.encodeBytes((u+":"+p).getBytes()));
}
private void updateStatus() {
try {
String s=status.getText().toString();
HttpPost post=new HttpPost("https://identi.ca/api/statuses/update.json");
post.addHeader("Authorization",
"Basic "+getCredentials());
List<NameValuePair> form=new ArrayList<NameValuePair>();
form.add(new BasicNameValuePair("status", s));
post.setEntity(new UrlEncodedFormEntity(form, HTTP.UTF_8));
ResponseHandler<String> responseHandler=new BasicResponseHandler();
String responseBody=client.execute(post, responseHandler);
JSONObject response=new JSONObject(responseBody);
}
catch (Throwable t) {
Log.e("Patchy", "Exception in updateStatus()", t);
goBlooey(t);
}
}

Categories

Resources