Android httpclient request and processing with entity - android

I do requests to my servlet
try {
Log.d(Constants.DEBUG_TAG_MAPS, "try");
HttpEntity entity = new StringEntity(json);
post.setEntity(entity);
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 15000);
HttpConnectionParams.setSoTimeout(httpParameters, 150000);
httpclient = new DefaultHttpClient(httpParameters);
BasicHttpResponse response = (BasicHttpResponse ) httpclient.execute(post);
Log.d(Constants.DEBUG_TAG_MAPS, "http status code : "+response.getStatusLine().getStatusCode());
if(response.getStatusLine().getStatusCode() == 200){
Log.d(Constants.DEBUG_TAG_MAPS, "response 200");
HttpEntity responseEntity = response.getEntity();
if (responseEntity!= null) {
Gson g = new Gson();
InputStream is = responseEntity.getContent();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader reader = new BufferedReader(isr);
try{
responseEntity.getContent();
String x = EntityUtils.toString(responseEntity);
}catch (Exception e) {
// TODO: handle exception
}
responseJSONObject = g.fromJson(reader, JSONResponseObject.class);
Log.d(Constants.DEBUG_TAG_MAPS_console, responseJSONObject.toString());
reader.close();
System.gc();
}
}
} catch (Exception e) {
e.printStackTrace();
}
/code>
and on line :
InputStream is = responseEntity.getContent();
app is crashing ...response code is 200 ...
I have looked on my tomcat logs and everything is ok. JSONResponseObject is filled with values and sended.
What could be the problem? How can I get stacktrace to logcat?
One maybe related problem:
I have well know "Couldn't et connection factory client" in logcat
Any of thing could causing that issue is not my case
api key is correct, path to correct debug.keystore
all permissions in manifest
uses-library android:name="com.google.android.maps in manifest as well
Map is displayed correctly, refreshing on zooming/moving.

Problem solved after anotate json objects with google.gson.annotations instead of just implementing serializable.

Related

Passing cookie with an HTTT GET

I am trying to get a list of user subreddits via the reddit api. Currently I am able to do a post for login which returns a cookie and modhash. Those are the parameters I'm passing to my method below. However each time I call the function I get an empty response:
"{}"
How can I pass a cookie and modhash via HTTPGET to get a valid response?
public void getUserSubreddits(String[] loginInfo){
HttpClient client = new DefaultHttpClient();
URL url = null;
try {
url = new URL("http://www.reddit.com/subreddits/mine/.json?limit=100");
HttpGet httpGet = new HttpGet(String.valueOf(url));
client.getParams().setParameter(CoreProtocolPNames.USER_AGENT, System.getProperty("http.agent"));
httpGet.addHeader("cookie", loginInfo[1]);
httpGet.addHeader("modhash", loginInfo[0]);
HttpResponse response = client.execute(httpGet);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
InputStream is = buf.getContent();
BufferedReader r = new BufferedReader(new InputStreamReader(is));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}
Log.d(TAG,total.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
It was a simple mistake. To anyone in the future trying this I solved the problem by using Chrome to inspect the headers of an active session on http://www.reddit.com/subreddits/mine/.json?limit=100 url and found that the cookie header started with:
reddit_session
So I removed the modhash changed the my header parameter to read:
httpGet.addHeader("cookie", "reddit_session="+loginInfo[1]+";");
With this I got a valid response.

Blank Response when doing JSON POST from Android

I am trying to post two json encoded values to my webservice using the below code. but i am not getting any response (Just Blank Output and No errors on LogCat). However, I have tried posting the same parameters from PHP to my webservice using cURL which works great.
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000);
HttpResponse response;
try {
json.put("name","email");
json.put("email", "email");
HttpPost post = new HttpPost(url);
post.setHeader("Content-Type", "application/json");
post.setHeader("Accept-Encoding", "application/json");
post.setHeader("Accept-Language", "en-US");
List<NameValuePair> ad = new ArrayList<NameValuePair>(2);
ad.add(new BasicNameValuePair("json", json.toString()));
post.setEntity(new UrlEncodedFormEntity(ad));
Log.i("main", "TestPOST - nVP = "+ad.toString());
response = client.execute(post);
if(response!=null) {
HttpEntity entity = response.getEntity();
output = EntityUtils.toString(entity,HTTP.UTF_8); //Get the data in the entity
}
} catch(Exception e) {
}
Try Getting your response by this
if (response.getStatusLine().getStatusCode() == 200)
{
HttpEntity entity = response.getEntity();
json = EntityUtils.toString(entity);
}
You're catching Exception (the super class) without logging. If an exception of any kind occurs in your try block the code will jump to the catch without any log.
Change this:
catch(Exception e){
}
with
catch (Exception e)
Log.e("myappname", "exception", e);
}
If there is no response, you should definitely check your catch exception e, since you didn't write anything in the clause, there might be something happening but you didn't notice.

Android:Trying to make an httpPost Request but keep getting connection timeout

I am really in pain right now please help me solve this issue.
I've previously also tried to make the http request to my localhost and it all works fine but right now it is not working and I don't know why.
I am trying to make the request from the following code.
HttpClient httpclient = new DefaultHttpClient();
String result="";
try
{
HttpPost httppost = new HttpPost("http://[ip]/php/untitled.php");
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(3);
nameValuePairs.add(new BasicNameValuePair("email",this.userEmail));
nameValuePairs.add(new BasicNameValuePair("pwd",this.userpassword));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity=response.getEntity();
if(entity!=null)
{
InputStream inputStream=entity.getContent();
result= convertStreamToString(inputStream);
}
}
catch (ClientProtocolException e)
{
Log.e("errorhai",e.getMessage());
}
catch (IOException e)
{
Log.e("errorhai",e.getMessage());
}
return result;
I've also added the internet permission but still it keeps saying
Connect to [ip] timed out.
When I enter the url in my browser it works fine but it is not working here.Please tell me what can be the causes of this problem ?
you can set the time out parameter to handle such type of exception :
HttpParams httpParameters = new BasicHttpParams();
/* Set the timeout in milliseconds until a connection is established.
The default value is zero, that means the timeout is not used.*/
int timeoutConnection = 60*1000*1;
HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
/* Set the default socket timeout (SO_TIMEOUT)
in milliseconds which is the timeout for waiting for data. */
int timeoutSocket = 60*1000*1;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
HttpClient client = new DefaultHttpClient(httpParameters);
//HttpClient client = new DefaultHttpClient();
HttpResponse httpResponse;
try {
/** Finally, we send our request using HTTP. This is the synchronous
long operation that we need to run on this thread. */
httpResponse = client.execute(request);
/*int responseCode = httpResponse.getStatusLine().getStatusCode();
String message = httpResponse.getStatusLine().getReasonPhrase();*/
HttpEntity entity = httpResponse.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
String res = convertStreamToString(instream);
MLog.v("HTTP RESPONSE : ", "Res :-"+res);
if(!res.trim().equalsIgnoreCase("[]")){
response.setResult(res);
response.setSuccess(true);
}else{
response.setSuccess(false);
response.setErrorMessage(AppConstant.RECORD_NOT_FOUND);
}
/** Closing the input stream will trigger connection release */
instream.close();
}else{
response.setSuccess(false);
response.setErrorMessage(AppConstant.NETWORK_ERROR);
}
}
catch (Exception e) {
//client.getConnectionManager().shutdown();
e.printStackTrace();
response.setSuccess(false);
response.setErrorMessage(AppConstant.NETWORK_ERROR);
}
//you can again try to send request , if your response is not sucess.
//retryHttpRequestIfNotSucess();
your problem might be related to the login. Is your script expecting a preemptive authetification? Do you have a error page for a failed login?
For requesting a page with preemptive http basic authentication i'm using the following code that is working. Have a try, if its working for you too.
DefaultHttpClient httpclient = null;
HttpParams params = new BasicHttpParams();
HttpResponse response = null;
HttpEntity entity = null;
// Set connection parameter
params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);
httpclient = new DefaultHttpClient(params);
// Create a post statement
HttpPost httppost = new HttpPost(Constants.urlLogin);
httppost.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.RFC_2965);
httppost.getParams().setParameter("http.protocol.single-cookie-header", true);
httppost.getParams().setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.BROWSER_COMPATIBILITY);
List<NameValuePair> nvps = new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("login_name", this.username));
nvps.add(new BasicNameValuePair("login_passwd", this.userpassword));
httppost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.UTF_8));
response = httpclient.execute(httppost);
entity = response.getEntity();
int statusCode = response.getStatusLine().getStatusCode();
String loadedContent = null;
if (entity != null)
{
loadedContent = EntityUtils.toString(entity, HTTP.UTF_8);
// loadedContent =
// Helper.convertStreamToString(entity.getContent());
entity.consumeContent();
}
if (statusCode != (HttpStatus.SC_OK))
{
throw new ServerCommunicationErrorException();
} else if (!loadedContent.contains("Logout"))
{
// Login failed
throw new LoginFailedException();
}
As you can see, i get a "not logged in" page as result, if the login fails to determine the login process. Further more i set some parameters, that might be also interesting for you. You can look here for more information on parameters.

Android service - data connection lost and can't restore

The background of my service: it implements LocationListener and in LocationManager instance (locMananager) registers for updates:
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
In onLocationChanged method it calls a method named recordTrace with a current location, which then calls getHttpResponse to send the location coordinates to a server. The latter method is as follows:
public InputStream getHttpResponse(String url, ArrayList<NameValuePair> params, int timeout) throws Exception {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, timeout);
httpClient.setParams(httpParams);
HttpPost post = new HttpPost(url);
if(params != null && !params.isEmpty()) {
try {
post.setEntity(new UrlEncodedFormEntity(params));
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "HttpPost.setEntity Error: " + e.getMessage());
lastError = "błąd HTTP";
}
}
CookieStore store = new BasicCookieStore();
if(localCookies != null && localCookies.size() > 0) {
for(int i = 0; i < localCookies.size(); i++) {
store.addCookie(localCookies.get(i));
}
}
HttpContext context = new BasicHttpContext();
context.setAttribute(ClientContext.COOKIE_STORE, store);
HttpResponse response = null;
HttpEntity entity = null;
InputStream content = null;
try {
response = httpClient.execute(post, context);
store = (CookieStore) context.getAttribute(ClientContext.COOKIE_STORE);
List<Cookie> cookies = store.getCookies();
if(cookies != null && cookies.size() > 0) {
localCookies = new ArrayList<BasicClientCookie>();
for(Cookie cookie : cookies) {
localCookies.add((BasicClientCookie) cookie);
}
}
entity = response.getEntity();
content = entity.getContent();
return content;
} catch (ClientProtocolException e) {
throw e;
} catch (IOException e) {
throw e;
} catch (Exception e) {
throw e;
}
}
params is a NameValuePair with prepared data, timeout is set to 5000 (5 seconds). ArrayList localCookies holds cookies saved before, after successful logging in (to keep the session).
The problem is: when I loose a mobile signal (i.e. when I go to a subway) and restore it, I get IOException, which is unrecoverable unless I restart the phone.
Any help would be appreciated. I'm loosing my mind and going bald!
Thanks,
Peter.
EDIT
I've done some research. After the method getHttpResponse is invoked, I utilize InputStream returned by it, but don't close it after all. Do you thing that might be the issue? Is this possible that the operator breaks the connection and then establishes a new one, whereas my InputStream somehow "keeps" the former connection and produces the problems with data transfer?
I added a finally block where now the InputSTream is closed. However, since it's hard to cause the problem on demand (it doesn't happen regularly), I can't check if closing stream solves it.
After a few days of testing it seems I've found the solution. Calling 2 methods solves the issue:
close the InputStream returned by httpResponse.getEntity()
shutdown the connection by executing httpClient.getConnectionManager().shutdown()
Code snippet of a complete request and response handling:
String url = "www.someurl.com";
ArrayList<NameValuePair> params = new ArrayList<NameValuePair>();
params.add(new BasicNameValuePair("login", "mylogin"));
params.add(new BasicNameValuePair("password", "mypassword"));
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
try {
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
InputStream content = httpEntity.getContent();
/*
* utilize content here...
*/
content.close(); // here's the point
httpClient.getConnectionManager().shutdown(); // the second important thing
}
catch (UnsupportedEncodingException e) {}
catch (ClientProtocolException e) {}
catch (IOException e) {}
I'm answering my own question since I've spent a lot of time on searching what's causing the problem and I think I can save somebody's time. After a few days the aplication is still working and doesn't break the connection.
Regards,
Peter.

Getting hebrew character from http response in json on android

I'm working on a project in which I need to get some data from my app engine server which contains hebrew characters (the data is sent in json).
On server side:
resp.setHeader("Content-Type", "application/json; charset=UTF-8");
PrintWriter out = resp.getWriter();
out.print(responeData.toString());
when I'm debugging the server I see that the response data seems fine (meaning, it's showing my hebrew characters.
On the client side (android):
After executing this code, the resultData i'm getting is with ??? instead hebrew characters.
I tried all different encodings such as 'windows-1255', 'iso-8859-8'
Does anyone knows what the problem is?
Thanks!
// Create new default http client
HttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 10000); // Timeout Limit
HttpConnectionParams.setSoTimeout(client.getParams(), 10000);
HttpResponse response;
HttpPost post = new HttpPost(serviceURL);
try {
StringEntity se = new StringEntity(requestPayload.toString());
post.addHeader(CustomHeader.TASK_NAME.getHeaderName(), taskName);
se.setContentType(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
post.setEntity(se);
// Execute the request
response = client.execute(post);
// Get the response status code
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) { // Ok
if (response != null) { // Checking response
InputStream in = response.getEntity().getContent(); // Get the data in the entity
retreturnVal = HttpCaller.readContentFromIS(in);
}
}
} catch (Exception e) {
Log.e("Error in connectivity layer, stacktrace: ", e.toString());
return null;
}
public static String readContentFromIS(InputStream in) throws IOException {
BufferedReader reader = new BufferedReader(
new InputStreamReader(in, "UTF-8"), 8);
StringBuffer sb = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
return sb.toString();
}
Assuming you are using a ServletResponse on your server, instead of calling
resp.setHeader("Content-Type", "application/json; charset=UTF-8");
you should call
resp.setContentType("application/json; charset=UTF-8");
This should have the effect of changing the encoding used in the call to getWriter() to UTF-8. I don't think that calling setHeader has the same side effect.
I had the same problem but I did
StringEntity se = new StringEntity(requestPayload.toString(), "UTF-8");
instead of
StringEntity se = new StringEntity(requestPayload.toString());
and it works fine for me, it's another solution.

Categories

Resources