I'm writing an Android application. It sends a HTTPPost to a server and receives the answer, when I use :
public final HttpResponse execute (HttpUriRequest request)
it's ok,
but when I try to use:
public T execute (HttpUriRequest request, ResponseHandler<? extends T> responseHandler)
it throws ClientProtocolException
because of some reasons I wanna use the second function, what should I do? What is the exception for ?
here is the code that uses the first function :
HttpPost httppost = new HttpPost("http://foo.Com/GeneralControls/Service.asmx/Login");
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpResponse response = httpclient.execute(httppost) ;
and here is the code that uses the second function:
HttpPost httppost = new HttpPost("http://foo.Com/GeneralControls/Service.asmx/Login");
DefaultHttpClient httpclient = new DefaultHttpClient();
ResponseHandler<String> responseHandler=new BasicResponseHandler();
String response = httpclient.execute(httppost , responseHandler) ;
throws ClientProtocolException.
See the below code is working fine for me
HttpContext localContext = new BasicHttpContext();
localContext.setAttribute(ClientContext.COOKIE_STORE,
Util.cookieStore);
try {
HttpResponse response = httpclient.execute(httppost,
localContext);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
But you are trying to pass ResponseHandler and it accepts httpContext
The problem was a protocol problem, the webservice was changing the Destination URL and it produced an Exception
Related
I want to do an HttpPost on Android to update a single row in a database. I do not need any response, verification, etc. So I am trying to simplify my code because I think what I have may be redundant.
This is what I have:
try {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url_select);
httpPost.setEntity(new UrlEncodedFormEntity(param));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
httpEntity.getContent();
} catch (Exception e) {
e.printStackTrace();
}
Do I need all of this? It seems I can just have
try {
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url_select);
httpPost.setEntity(new UrlEncodedFormEntity(param));
httpClient.execute(httpPost);
} catch (Exception e) {
e.printStackTrace();
}
Is this correct?
I won't eat when I'm not hungry :)
Yes. The second part is good enough. No need to get the response object there if you don't really need it. That is fine.
You may also want to check AQuery library which simplifies Http connections:
https://code.google.com/p/android-query/
in my program I have http get which gets data from PHP script. This code is present in async task. This works fine.
But now I want to do HTTP post, where I, the android client, post data to the PHP script, it quires the DB and returns the result of that.
But this is what is confusing me.
Can I get a response from a HTTP post? Or do i need a combination of post and get?
This question I don't expect an answer but if anyone can advise on this would be great. I have one async task which does the HTTP get. Now i want to use the same async to do either HTTP get or post but not both. Is this possible?
Thank you
Here John. A small snippet. My problem is the HTTP StatusLine httpStatus and http entity it does not recognise any of the responses because they are in if statements so the compiler thinks they will not be defined.
if(params[1] == "GETRESULT")
{
HttpGet get = new HttpGet(params[0]);
HttpResponse r = client.execute(get);
}
else //we are posting
{
HttpPost post = new HttpPost(params[0]);
HttpResponse r = client.execute(post);
}
StatusLine httpStatus = r.getStatusLine();
HttpEntity e = r.getEntity();
You can get a response with post
You can use the same async method as long as you have some logic that changes the request type to POST or GET depending on what you want to do.
some info on HttpPost
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.yoursite.com/script.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(2);
nameValuePairs.add(new BasicNameValuePair("id", "12345"));
nameValuePairs.add(new BasicNameValuePair("stringdata", "AndDev is Cool!"));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
For your code to work you need to declare the Response outside of your if/blocks:
HttpResponse r = null;
if(params[1] == "GETRESULT")
{
HttpGet get = new HttpGet(params[0]);
r = client.execute(get);
}
else //we are posting
{
HttpPost post = new HttpPost(params[0]);
r = client.execute(post);
}
StatusLine httpStatus = r.getStatusLine();
HttpEntity e = r.getEntity();
Move your HttpResponse r above the if/else statement as HttpResponse someVariable; then you can access it inside your else, and read the result afterwards. You also have to check for NullPointerException, with a try / catch block.
For example like this :
HttpResponse r;
if(params[1] == "GETRESULT")
{
HttpGet get = new HttpGet(params[0]);
r = client.execute(get);
}
else //we are posting
{
HttpPost post = new HttpPost(params[0]);
r = client.execute(post);
}
StatusLine httpStatus = r.getStatusLine();
try {
HttpEntity e = r.getEntity();
} catch (NullPointerException e) {
//Error handling
}
I hava this code
public static String methodPost(final String url, final String dataToPost) throws ClientProtocolException,
IOException, IllegalStateException, Exception {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
StringEntity se = new StringEntity(dataToPost);
se.setContentEncoding("UTF-8");
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httpPost.setEntity(se);
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
return streamToString(httpEntity.getContent());
}
I post this in IPHONE and work perfectly:
#"{\"var1\":\"Value1\"}{\"var2\":[{\"item1\":\"1\"},{\"item1\":\"Value2\"}]}"
when I post also in ANDROID.
Response return HTTP 1 400
example:
methodPost(url, "{\"var1\":\"Value1\"}{\"var2\":[{\"item1\":\"1\"},{\"item1\":\"Value2\"}]}");
but, I post this
methodPost(url, "{\"var1\":\"Value1\"}{\"var2\":\"Value2\"}");
this work perfectly only when I use "[ ]" i have some error
sorry for my english :)
I'm POSTing some data to a server that is answering a 302 Moved Temporarily.
I want HttpClient to follow the redirect and automatically GET the new location, as I believe it's the default behaviour of HttpClient. However, I'm getting an exception and not following the redirect :(
Here's the relevant piece of code, any ideas will be appreciated:
HttpParams httpParams = new BasicHttpParams();
HttpClientParams.setRedirecting(httpParams, true);
SchemeRegistry schemeRegistry = registerFactories();
ClientConnectionManager clientConnectionManager = new ThreadSafeClientConnManager(httpParams, schemeRegistry);
HttpClient httpClient = new DefaultHttpClient(clientConnectionManager, httpParams)
HttpPost postRequest = new HttpPost(url);
postRequest.setHeader(HTTP.CONTENT_TYPE, contentType);
postRequest.setHeader(ACCEPT, contentType);
if (requestBodyString != null) {
postRequest.setEntity(new StringEntity(requestBodyString));
}
return httpClient.execute(postRequest, responseHandler);
For HttpClient 4.3:
HttpClient instance = HttpClientBuilder.create()
.setRedirectStrategy(new LaxRedirectStrategy()).build();
For HttpClient 4.2:
DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectStrategy(new LaxRedirectStrategy());
For HttpClient < 4.2:
DefaultHttpClient client = new DefaultHttpClient();
client.setRedirectStrategy(new DefaultRedirectStrategy() {
/** Redirectable methods. */
private String[] REDIRECT_METHODS = new String[] {
HttpGet.METHOD_NAME, HttpPost.METHOD_NAME, HttpHead.METHOD_NAME
};
#Override
protected boolean isRedirectable(String method) {
for (String m : REDIRECT_METHODS) {
if (m.equalsIgnoreCase(method)) {
return true;
}
}
return false;
}
});
The default behaviour of HttpClient is compliant with the requirements of the HTTP specification (RFC 2616)
10.3.3 302 Found
...
If the 302 status code is received in response to a request other
than GET or HEAD, the user agent MUST NOT automatically redirect the
request unless it can be confirmed by the user, since this might
change the conditions under which the request was issued.
You can override the default behaviour of HttpClient by sub-classing DefaultRedirectStrategy and overriding its #isRedirected() method.
It seem http redirect is disable by default. I try to enable, it work but I'm still got error with my problem. But we still can handle redirection pragmatically. I think your problem can solve:
So old code:
AndroidHttpClient httpClient = AndroidHttpClient.newInstance("User-Agent");
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
long contentSize = httpResponse.getEntity().getContentLength();
This code will return contentSize = -1 if http redirect happend
And then I handle redirect by myself after trying enable default follow redirection
AndroidHttpClient client;
HttpGet httpGet;
HttpResponse response;
HttpHeader httpHeader;
private void handleHTTPRedirect(String url) throws IOException {
if (client != null)
client.close();
client = AndroidHttpClient.newInstance("User-Agent");
httpGet = new HttpGet(Network.encodeUrl(url));
response = client.execute(httpGet);
httpHeader = response.getHeaders("Location");
while (httpHeader.length > 0) {
client.close();
client = AndroidHttpClient.newInstance("User-Agent");
httpGet = new HttpGet(Network.encodeUrl(httpHeader[0].getValue()));
response = client.execute(httpGet);
httpHeader = response.getHeaders("Location");
}
}
In use
handleHTTPRedirect(url);
long contentSize = httpResponse.getEntity().getContentLength();
Thanks
Nguyen
My solution is using HttClient. I had to send the response back to the caller. This is my solution
CloseableHttpClient httpClient = HttpClients.custom()
.setRedirectStrategy(new LaxRedirectStrategy())
.build();
//this reads the input stream from POST
ServletInputStream str = request.getInputStream();
HttpPost httpPost = new HttpPost(path);
HttpEntity postParams = new InputStreamEntity(str);
httpPost.setEntity(postParams);
HttpResponse httpResponse = null ;
int responseCode = -1 ;
StringBuffer response = new StringBuffer();
try {
httpResponse = httpClient.execute(httpPost);
responseCode = httpResponse.getStatusLine().getStatusCode();
logger.info("POST Response Status:: {} for file {} ", responseCode, request.getQueryString());
//return httpResponse ;
BufferedReader reader = new BufferedReader(new InputStreamReader(
httpResponse.getEntity().getContent()));
String inputLine;
while ((inputLine = reader.readLine()) != null) {
response.append(inputLine);
}
reader.close();
logger.info(" Final Complete Response {} " + response.toString());
httpClient.close();
} catch (Exception e) {
logger.error("Exception ", e);
} finally {
IOUtils.closeQuietly(httpClient);
}
// Return the response back to caller
return new ResponseEntity<String>(response.toString(), HttpStatus.ACCEPTED);
For HttpClient v5, just use the below:
httpClient = HttpClientBuilder.create()
.setRedirectStrategy(new DefaultRedirectStrategy() {
#Override
public boolean isRedirected(HttpRequest request, HttpResponse response, HttpContext context)
throws ProtocolException {
return false;
}
}).build();
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);
}
}