Android HttpEntry read hang on Droid x - java

I've been working on a web-based android app , and we want the app to post data to server and read the response as JSONString , the code was tested on 3 different devices and all result ok , except for Droid X , it just hangs up on reading the inputStream from HttpResponse.
Here is my code :
HttpResponse response = mClient.execute(mPost);
StatusLine status_line = response.getStatusLine();
int status_code = status_line.getStatusCode();
/*
* Not ok Response
*/
if (status_code != 200){
mBusy = false;
mListener.log("Error Status code = "+String.valueOf(status_code));
return false;
}
HttpEntity entry = response.getEntity();
BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent(), "UTF-8"));
mResponse = reader.readLine();
Any ideas what should I do ?

I found out that the problem source was using android's default HTTP Client.
instead I used :
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
HttpProtocolParams.setUseExpectContinue(params, false);
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 10000);
ConnManagerParams.setMaxTotalConnections(params, 100);
ConnManagerParams.setTimeout(params, 30000);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http",PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https",PlainSocketFactory.getSocketFactory(), 80));
ThreadSafeClientConnManager manager = new ThreadSafeClientConnManager(params, registry);
mClient = new DefaultHttpClient(manager, params);
instead of :
mClient = new DefaultHttpClient();
hope that helps someone.

Related

Apache HttpClient 4.0.1- HttpPut No content to map due to end-of-input\n Error

I have a spring restful api and, I am trying to do the update over restful api using HttpPut method with Apache HttpClient 4.0.1 as below
import groovy.json.JsonBuilder
import org.apache.http.client.methods.HttpPut
import org.apache.http.entity.StringEntity
import groovy.json.JsonSlurper
import org.apache.commons.io.output.ByteArrayOutputStream;
def httpConnector = applicationContext.getBean('httpConnector')
String apiURL = "https://localhost:7443/api/ruleConfigurations/29"
def putRequest = new HttpPut(apiURL);
def testJson = new JsonBuilder()
root = testJson name: "test_name", displayName: "test_display_name", active: "false" , value: "test_value"
println "testJson = "+testJson.toString()
def stringEntity = new StringEntity(testJson.toString());
putRequest.setHeader("Accept", "application/json");
putRequest.setHeader("Content-type", "application/json");
def httpClient = httpConnector.getHttpClient()
def putResponse = httpClient.execute(putRequest)
def resCode = putResponse.getStatusLine().getStatusCode()
if(resCode==200){
println "succesfully updated Rule config"
}
else {
println "Response Code = ${resCode} Error in updating Rule config"
println "error message = "+getResponseData(putResponse)
}
def getResponseData(def response) throws java.io.IOException {
byte[] responseData
InputStream responseStream = response.getEntity().getContent()
try {
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()
byteArrayOutputStream.write(responseStream)
responseData = byteArrayOutputStream.toByteArray()
} finally {
responseStream.close()
}
return new String(responseData,'utf-8')
}
Below is the method for httpConnector.getHttpClient()
private DefaultHttpClient getHttpClient() {
if (httpClient != null) return httpClient;
final int MAX_CONNECTIONS = 300;
CookieStore cookieStore = new BasicCookieStore();
httpContext = new BasicHttpContext();
httpContext.setAttribute(ClientContext.COOKIE_STORE, cookieStore);
HttpParams params = new BasicHttpParams();
ConnManagerParams.setMaxTotalConnections(params,MAX_CONNECTIONS);
ConnManagerParams.setTimeout(params, 20000);
HttpConnectionParams.setSoTimeout(params, 240000);
HttpConnectionParams.setConnectionTimeout(params,30000);
ConnPerRouteBean connPerRoute = new ConnPerRouteBean(MAX_CONNECTIONS);
ConnManagerParams.setMaxConnectionsPerRoute(params, connPerRoute);
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 8080));
schemeRegistry.register(new Scheme("https", getSockectFactory(), 8443));
ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
def httpClient = new DefaultHttpClient(cm, params);
return httpClient;
}
Below is the output am getting while trying to do the update over restful api
testJson = {"name":"test_name","displayName":"test_display_name","active":"false","value":"test_value"}
Response Code = 400 Error in updating Rule config
error message = {
"cause":{
"cause":null,
"message":"No content to map due to end-of-input\n at [Source: org.apache.catalina.connector.CoyoteInputStream#5438c5f7; line: 1, column: 0]"
},
"message":"Could not read an object of type class com.validation.entity.RuleConfiguration from the request!; nested exception is com.fasterxml.jackson.databind.JsonMappingException: No content to map due to end-of-input\n at [Source: org.apache.catalina.connector.CoyoteInputStream#5438c5f7; line: 1, column: 0]"
}
If I use the same testJson for HttpPut in postman it works fine
Am not sure why am getting No content to map due to end-of-input\n error for HttpPut with the Apache HttpClient 4.0.1, can someone please help?
In the example you have shown you are not calling
putRequest.setEntity(stringEntity)
so the request you send has empty body.

MultipartEntity Files not uploading through device

Possibly this is a duplicate question but I have already tried all answer of this site but none of this working!
I am using MultipartEntity for image upload. It's working completely fine in Emulator but When I check in device its not working.
Below my code
HttpParams params = new BasicHttpParams();
params.setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP);
HttpClient httpClient = new DefaultHttpClient(params);
HttpContext localContext = new BasicHttpContext();
HttpPost httpPost = new HttpPost("http://url.com/webservice_uploadvideo.php");
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.STRICT);
FileBody filebodyVideopre = new FileBody(new File(videoUploadpathPre)); //pre
entity.addPart("fin_detail", filebodyVideopre);
httpPost.setEntity(entity);
HttpResponse response = httpClient.execute(httpPost, localContext);
Here's my working code for multi-part image uploading. Yes it works in real device.
private int uploadImage(String selectedImagePath) {
try {
HttpClient client = new DefaultHttpClient();
File file = new File(selectedImagePath);
HttpPost post = new HttpPost(Constants.URL);
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,
Constants.BOUNDARY, Charset.defaultCharset());
entity.addPart(Constants.MULTIPART_FORM_DATA_NAME, new FileBody(file));
post.setHeader("Accept", "application/json");
post.setHeader("Content-Type", "multipart/form-data; boundary=" + Constants.BOUNDARY);
post.setEntity(entity);
HttpResponse response = client.execute(post);
HttpEntity httpEntity = response.getEntity();
int status = response.getStatusLine().getStatusCode();
return status;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}

multipart request on Android goes to timeout

I Need to upload one file from my Android using multipart and tried with the below code but with no luck.
I got a connection timeout exception and tried with different code having the same result.
try
{
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(URL);
MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create();
entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
entityBuilder.addTextBody(USER_ID, "DFD");
entityBuilder.addTextBody(NAME, "DFD");
String filepath = Environment.getExternalStorageDirectory() + "/Download/myImage.jpg";
Log.d(MULTIPART_TAG, filepath);
File file = new File(filepath);
if(file != null)
{
entityBuilder.addBinaryBody("IMAGE", file);
}
HttpEntity entity = entityBuilder.build();
post.setEntity(entity);
HttpResponse response = client.execute(post);
HttpEntity httpEntity = response.getEntity();
String result = EntityUtils.toString(httpEntity);
Log.v("result", result);
}
catch(Exception e)
{
e.printStackTrace();
}
Here is the exception that I get:
08-06 17:49:03.006: W/System.err(24761): Caused by:
libcore.io.ErrnoException: connect failed: ETIMEDOUT (Connection timed
out)
I also tried with those solutions:
https://stackoverflow.com/a/19188010/1948785
and with the deprecated class MultipartEntity
My second question is what is the meaning of this warning (I dont know if it is related with my problem but I get it when performing the request):
08-06 17:45:53.461: W/dalvikvm(24761): VFY: unable to resolve static
field 3008 (INSTANCE) in
Lorg/apache/http/message/BasicHeaderValueParser;
The libs I am using are those:
httpclient-4.3.4.jar
httpcore-4.3.2.jar
httpmime-4.3.4.jar
Try to set timeout duration of HttpClient.
int TIMEOUT_MILLISEC = 20000; // = 20 seconds
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, TIMEOUT_MILLISEC);
HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT_MILLISEC);
HttpClient client = new DefaultHttpClient(httpParams);
Try this ,
DefaultHttpClient httpClient = new DefaultHttpClient();
// yourimagefile is your imagefile
HttpPost httpPostRequest = new HttpPost(URL);
// Try This
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
MultipartEntity mpEntity = new MultipartEntity();
ContentBody cbFile = new FileBody(yourimagefile, "image/jpeg");
mpEntity.addPart("file", cbFile);
httpPostRequest.setEntity(mpEntity);
HttpResponse response = (HttpResponse) httpclient.execute(httpPostRequest);
Check the size of the image. It might be that the image is too large and it is taking a long period of time to upload and the server is issuing a timeout on that connection.

Android 4.0.3 https post returns empty, http works, both works on 2.0.3

I'm connecting my Application to a REST type webservice. I'm using the apache http library, the request is a standard post request, ran in a background thread.
Now my problem is that if I'm using
http://myserver.com/api/command
it works and I get the proper response, but the same url with https:
https://myserver.com/api/command
I get an empty response. The http header is even 200 OK.
BOTH of these work on 2.0.3 but not on 4.0.3. On 4.0.3 the API seems to work only if I use plain http, with https I get empty responses.
This is the code:
#Override
protected HttpResponse doInBackground(String... params) {
String link = params[0];
HttpClient client = createHttpClient();
try {
HashMap<String, ContentBody> files = ApiManager.getFiles();
MultipartEntity mpEntity = new MultipartEntity();
if(files != null) {
for(String i : files.keySet()) {
ContentBody k = files.get(i);
mpEntity.addPart(i, k);
}
}
if(this.callParameters != null) {
for(NameValuePair i : this.callParameters) {
StringBody sb = new StringBody((String)i.getValue(),"text/plain",Charset.forName("UTF-8"));
mpEntity.addPart(i.getName(), sb);
}
}
httppost.setEntity(mpEntity);
// Execute HTTP Post Request
Log.d("ApiTask","Executing request: "+httppost.getRequestLine());
HttpResponse response = null;
response = client.execute(httppost);
client.getConnectionManager().shutdown();
return response;
}
catch(UnknownHostException e) {
exception = e;
return null;
}
catch (IOException e) {
exception = e;
return null;
}
catch(Exception e) {
return null;
}
}
#Override
protected void onPostExecute(HttpResponse result) {
System.out.println("STATUS:"+result.getStatusLine());
try {
StringBuilder responseText = this.inputStreamToString(result.getEntity().getContent());
System.out.println("RESPONSE:"+responseText);
}
catch(Exception e) {
System.out.println("Error");
}
}
private HttpClient createHttpClient() {
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.DEFAULT_CONTENT_CHARSET);
HttpProtocolParams.setUseExpectContinue(params, true);
HttpConnectionParams.setConnectionTimeout(params, 10000);
HttpConnectionParams.setSoTimeout(params, 10000);
SchemeRegistry schReg = new SchemeRegistry();
schReg.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
schReg.register(new Scheme("https", SSLSocketFactory.getSocketFactory(), 443));
ClientConnectionManager conMgr = new ThreadSafeClientConnManager(params, schReg);
return new DefaultHttpClient(conMgr, params);
}
Thank you in advance

Https post request using curl : Android

I am trying to execute a https post request using curl. When I execute this request, I am neither getting any response nor any error or exception. Help or any clue about what's going wrong here is appreciated. Thanks.
curl command line format :
curl -X POST \
-F 'image=#filename.png;type=image/png' \
-F 'svgz=#filename.svgz;type=image/svg+xml' \
-F 'json={
"text" : "Hello world!",
"templateid" : "0010",
"timestamp" : "1342683312",
"location" : [ 37.7793, -122.4192 ],
"facebook" :
{
"id": "738124695",
"access_token": "<VALID_USER_FACEBOOK_TOKEN_WITH_PUBLISH_ACTIONS_PERMISSIONS",
"expiration_date": "1342683312"
}
};type=application/json' \
https://sample.com/api/posts
Facebook posting code :
public static void uploadToFB() {
HttpClient client = getNewHttpClient();
HttpPost httpost = new HttpPost("https://sample.com/api/posts");
httpost.addHeader("image", "filename.png");
httpost.addHeader("svgz", "filename.svgz");
httpost.addHeader("type", "application/json");
httpost.setHeader("Content-type", "application/json");
JSONObject data = new JSONObject();
JSONObject facebook = new JSONObject();
JSONArray location = new JSONArray();
HttpResponse response = null;
try {
data.put("text","Hello world!");
data.put("templateid","0010");
data.put("timestamp","2012-07-08 09:00:45.312195368+00:00");
location.put(37.7793);
location.put( -122.4192);
data.put("location", location);
facebook.put("id", "738124695");
facebook.put("access_token", "AAADdF92joPABAKmRojBuXZAZAP"+
"qF8ZAxM2bM"+
"UnIErUSYZB85y5vIHAZDZD");
facebook.put("expiration_date", "2013-07-07T 22:00:00Z");
data.put("facebook", facebook);
System.out.println(" ---- data ----- "+data);
StringEntity stringEntity = new StringEntity(data.toString());
httpost.setEntity(stringEntity);
try {
response = client.execute(httpost);
System.out.println(" --- response --- "+response);
HttpEntity entity = response.getEntity();
// If the response does not enclose an entity, there is no need
// to worry about connection release
if(entity != null) {
// A Simple Response Read
InputStream instream = entity.getContent();
String result = convertStreamToString(instream);
System.out.println(" ---- result ---- "+result);
// Closing the input stream will trigger connection release
instream.close();
}
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (JSONException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
It was an untrusted network, so, for that I did something like below as in this link.
private static HttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
trustStore.load(null, null);
SSLSocketFactory sf = new MySSLSocketFactory(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));
ClientConnectionManager ccm = new ThreadSafeClientConnManager(params, registry);
return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
BufferedReader in = null;
StringBuffer sb = new StringBuffer();
BufferedReader inPost = null;
try {
DefaultHttpClient httpclient = new DefaultHttpClient();
HttpPost httpost = new HttpPost(mURL);
httpost.setHeader("Accept","*/*");
httpost.setHeader("Content-Type", "application/x-www-form-urlencoded");
List <NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("testkey1", "myvalue1"));
nvps.add(new BasicNameValuePair("testkey2", "myvalue2"));
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
HttpResponse response = httpclient.execute(httpost);
HttpEntity entity = response.getEntity();
inPost = new BufferedReader(new InputStreamReader(entity.getContent()));
String linePost = "";
String NLPOST = System.getProperty("line.separator");
while ((linePost = inPost.readLine()) != null) {
sb.append(linePost + NLPOST);
}
inPost.close();
if (entity != null) {
entity.consumeContent();
}
httpclient.getConnectionManager().shutdown();
also more on this link..
http://www.softwarepassion.com/android-series-get-post-and-multipart-post-requests/
After some hard time I got solution for my problem. Now, using MultipartEntity, I am able to send data to server like below.
HttpClient httpClient = getHttpClient();
HttpPost httpost = new HttpPost("https://sample.com/api/posts");
MultipartEntity mpEntity = new MultipartEntity();
ContentBody cbFile1 = new FileBody(new File("file.png"), "image/png");
mpEntity.addPart("image", cbFile1);
ContentBody cbFile2 = new FileBody(new File("file.svg"), "image/svg+xml");
mpEntity.addPart("svgz", cbFile2);
ContentBody cbFile3 = new StringBody(getJsonData().toString(), "application/json", Charset.forName("UTF-8"));
mpEntity.addPart("json", cbFile3);
httpost.setEntity(mpEntity);

Categories

Resources