How to make a Http Get fast request? - java

actually i have a correct code that makes a http petition to twitter and get's some tweets from a user codified with JSON (it gets a file .json)
It's ok, it works fine, but it takes a loooooooooooooot of time making the request, debugging i can see that the problem is on the line HttpResponse response = httpclient.execute(httpget);
On that line it gets stuck a lot of seconds when the number of tweets is more than 3 or 4 tweets. If you are requesting 20 tweets it takes 10-15 seconds to get them.
It is a problem of the java/android http get method i am using, because if i make the request by url on firefox, then, it is super fast.
How to make this http get request by a faster way?
This is my actual and slow code:
public List<String> RetrieveTweets(String name, int num) //da todas las posiciones dado un email
{
// https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name=charliesheen&count=2
List<String> tweetsList= new ArrayList<String>();
String result = "";
//http get
InputStream is=null;
try{
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("https://api.twitter.com/1/statuses/user_timeline.json?include_entities=true&include_rts=true&screen_name=" + name +"&count="+ num);
HttpResponse response = httpclient.execute(httpget);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}catch(Exception e){
Log.e("log_tag", "Error in http connection "+e.toString());
}
//convert response to string
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result=sb.toString();
}catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
//parse json data
try{
JSONArray jArray = new JSONArray(result);
for(int i=0;i<jArray.length();i++)
{
JSONObject json_data = jArray.getJSONObject(i);
tweetsList.add(json_data.getString("text")); //text es el nombre del campo del tweet
}
}
catch(JSONException e){
Log.e("log_tag", "Error parsing data "+e.toString());
}
return tweetsList;
}

Are you required to use https version to get the statuses? Https will be slower than http because of two things:
Initial connect requires a handshake negotiation for deciding cipter algorithm + session key
Once the handshake is established, each way of communication requires encryption/decryption of the message.
If you are required to us SSL, you could try instantiating the HttpClient once and not instantiating every time in the method. Hopefully, it will keep the session alive and thus avoiding the handshake which can be costly if you initiate it every time.

Related

Android application doesn't read entire HTTP response

I have written a web-service in Java. This web-service is hosted in TOMCAT. I am returning a JSON string. The JSON string is as follows:
accountDetailsNodes = [{mobileNumber=01948330292, errorMessage=null, customerCode=59744000002, photo=a string of 35536 charaters , accountOpenDate=null, errorFlag=N, customerNumber=4, customerName=Md. Saifur Hossain , accountID=2, accountTypeId=13, accountTypeDescription=Savings Account, customerPointId=1, balance=100000037640.50, accountTile=Md. Saifur Hossain}]
The length of the JSON string is 32613. But the full response is not coming to android apps. I think there may be some limitation on sending response from Tomcat. How can I overcome this limitation of Tomcat?
Updated:
This is my code to generate JSON.
try {
List<Map<String, Object>> list = new ArrayList<Map<String, Object>>();
JSONObject json = new JSONObject();
CashDepositDao dao = new CashDepositDao();
for (CashDepositModel bo : dao.getAccountDetals(accountNo,branchCode)) {
Map<String, Object> map = new HashMap<String, Object>();
map.put("accountTile", bo.getAccountTitle());
map.put("accountOpenDate", bo.getAccountOpenDate());
map.put("mobileNumber", bo.getMobileNumber());
map.put("balance", bo.getBalance());
map.put("accountTypeId", bo.getAccountTypeID());
map.put("accountTypeDescription", bo.getAccountTypeDescription());
map.put("accountID", bo.getAccountID());
map.put("customerNumber", bo.getCustomerNumber());
map.put("customerCode", bo.getCustomerCode());
map.put("customerName", bo.getCustomerName());
map.put("customerPointId", bo.getCustomerPointID());
map.put("photo", bo.getPhoto());
map.put("errorMessage", bo.getErrorMessage());
map.put("errorFlag", bo.getErrorFlage());
list.add(map);
json.put("accountDetailsNodes", list);
}
System.out.println("accountDetailsNodes = " + list);
response.addHeader("Access-Control-Allow-Origin", "*");
response.setContentType("application/json");
response.setCharacterEncoding("UTF-8");
response.getWriter().print(json.toString());
response.getWriter().flush();
// System.out.println("Response Completed... ");
} catch (Exception ex) {
Logger.getLogger(SourecAccountDetailsSV.class.getName()).log(Level.SEVERE, null, ex);
}
Sending And Getting response from Mobile App:
I am sending and getting the response using the following code:
public JSONObject makeHttpRequest(String url, String method,
List<NameValuePair> params) {
// Making HTTP request
try {
// check for request method
if(method == "POST"){
// request method is POST
// defaultHttpClient
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(params));
HttpResponse httpResponse = httpClient.execute(httpPost);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}else if(method == "GET"){
// request method is GET
DefaultHttpClient httpClient = new DefaultHttpClient();
String paramString = URLEncodedUtils.format(params, "utf-8");
url += "?" + paramString;
HttpGet httpGet = new HttpGet(url);
HttpResponse httpResponse = httpClient.execute(httpGet);
HttpEntity httpEntity = httpResponse.getEntity();
is = httpEntity.getContent();
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
json = sb.toString();
System.out.println(json);
} catch (Exception e) {
Log.e("Buffer Error", "Error converting result " + e.toString());
}
// try parse the string to a JSON object
try {
jObj = new JSONObject(json);
} catch (JSONException e) {
Log.e("JSON Parser", "Error parsing data " + e.toString());
}
// return JSON String
return jObj;
}
I have printed the string received in this method . Surprisingly, the full string is not received in this method.
How can I overcome this limitation of tomcat ?
Tomcat can send arbitrary length strings, and even if there was a limit, it wouldn't be measured in kilobytes but in orders of magnitude more. There is no tomcat limitation that you need to overcome. If your browser receives the full string, so can any other app.
As you're using json.toString() anyways, you could explicitly set the Content-Length header and see if this makes a difference. Stop worrying about Tomcat and double check if your Android App has some problems parsing a json response of this size, or if any network component in between limits your response in some way.
Edit: It's not Tomcat's problem, it's on the Android side and your answer is in the comments to the question.
The first problem is in what's proposed as "duplicate" question: You must not compare String with == as you do. Add else System.out.print("unexpected"); to your first if/else block to illustrate.
The second problem is that we have no clue where you get is from. As it looks now, it could be overridden by parallel requests (it's probably a class member?) - or due to the wrong string comparison never be initialized at all (leading to your problem that you can't see any content at all on the Android side, despite tomcat sending it). Make it a local variable, as proposed by EJP in his/her comment.
I think there may be some limitation on sending response from Tomcat.
There isn't.
How can I overcome this limitation of Tomcat?
There is no such limitation.
I am sending and getting the response using the following code:
public JSONObject makeHttpRequest(String url, String method,
List<NameValuePair> params) {
// Making HTTP request
try {
// check for request method
if(method == "POST"){
Here you are incorrectly comparing strings. You should use equals(), not ==.
// ...
}else if(method == "GET"){
Ditto.
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "iso-8859-1"), 8);
Here you are using is which may not have been initialized at all. It appears to be a member variable, so it is probably still null, so at this point I would expect a NullPointerException. is should of course be a local variable in this method.
I have printed the string received in this method. Surprisingly, the full string is not received in this method.
What is surprising is that anything is received, if that's what you're claiming. I would have expected an NPE.

How send a json to server

I have a json that will be send to server in "Post".
There are parameters in json for 3 images to upload on server using multipart. I have no additional parameter to send it Multipart.
When I try it "PostMan" app of chrome to test it.
Here are 2 cases-
case 1:- select "raw" option in body & set content type "application json" in POSTMAN
Then all data had send to server expect images.
Case 2: Select "form-data" option in PostMan.
I have only to send some part of Json like images, certificates, venue, address, contact, achievement, level, at_home, certified, but unable to failed "coach_free_batch","coach_session" & "sports" section of json.
Please provide solution to upload all fields on server
Either idea to send "sports","coach_free_session" in second case by Postman or any other idea
Json
{"coach_free_batch":[{"sport_id":"10","batch_timing":{"end_time":"1:51 PM","start_time":"12:51 PM"},{"end_time":"11:51 AM","start_time":"10:51 AM"},{"end_time":"1:51 PM","start_time":"11:51 AM"}]},
{"sport_id":"4","batch_timing":[{"end_time":"1:52 PM","start_time":"12:52 PM"},
{"end_time":"3:52 PM","start_time":"2:52 PM"},{"end_time":"3:54 PM","start_time":"2:52 PM"}]}],
"coach_session":[{"timing":"2 Hour","rate":"24"},{"timing":"1 Hour","rate":"40"},
{"timing":"3 Hour","rate":"70"}],
"achievement":" national level",
"level":"Competitive","user_token":"XJnQCAz1ssuUCjgHtFs6","at_home":"1",
"sports":[{"user_sports_label_id":"7","sport_id":"2"},{"user_sports_label_id":"10","sport_id":"3"},
{"user_sports_label_id":"3","sport_id":"4"}],
"images":[{"image":"xxx"},
{"image":"xxx"}],
"experience":" more than 2 year","venue":"address","contact":"8236968542",
"certificates":[{"certificate":"certificate1"},{"certificate":"certifocate2"},{"certificate":"certificate3"}]}
Method for send Data as raw
public static String sendDataInJSONFormat(String url, String json) {
// initialize
InputStream is = null;
String result = null;
String url1 = "";
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
httppost.setHeader("Content-Type",
"multipart/form-data; application/json; charset=UTF-8;text/plain");
HttpParams httpParameters = new BasicHttpParams();
int timeoutSocket = 25000;
HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);
StringEntity se = new StringEntity(json.toString(), "UTF-8");
httppost.setEntity(se);
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
e.printStackTrace();
}
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(
is, "UTF-8"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
e.printStackTrace();
}
return result;
}

Having some trouble connecting an android app to an online database

I have been running into some issues with a small Android project for school. I need to request a password from an online database via a .php by sending it the username. It should return an encrypted password. But there seems to be something wrong with the method I use to connect to the database and receive the password. LogCat gives me these:
Error in HTTP connection java.net.UnknownHostException: boekenapp.atwebpages.com
Error converting result java.lang.NullPointerException
Error parsing data org.json.JSONException: end of input at character 0 of
So my question: What did I do wrong?/What do I need to change to make it work?
The code:
public static String phpconnect(String name, String value) {
String result = "";
InputStream is = null;
//variables to send to database
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair(name,value));
//HTTP post
try{
HttpClient httpclient = new DefaultHttpClient();
URI connection = new URI("http://boekenapp.atwebpages.com/phpscript.php");
HttpPost httppost = new HttpPost(connection);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch(Exception e) {
Log.e("log_tag", "Error in HTTP connection "+e.toString());
}
//convert response to string
try{
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"iso-8859-1"),8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result=sb.toString();
} catch(Exception e){
Log.e("log_tag", "Error converting result "+e.toString());
}
//parse JSON data
try{
JSONArray jArray = new JSONArray(result);
for(int i=0;i<jArray.length();i++){
JSONObject json_data = jArray.getJSONObject(i);
Log.i("log_tag","userid: "+json_data.getInt("userid")+", password: "+json_data.getString("password"));
}
} catch(JSONException e) {
Log.e("log_tag", "Error parsing data "+e.toString());
}
return "";
}
The second try block will always execute, as you only log in the first catch block.
You should consider a return statement or a throw statement. An alternative is to embed the second try block inside the first one, but that's less readable maybe.
In your case, the problem is that the connection itself fails. Are you sure you have network up ? Can you ping the host from your computer and from Android (you can use adb shell ping <host> on CLI).
And don't truncate the error stacks on their first line, a stack has to be read fully, top-down until you find your piece of code that is causing the bug.
First of all the URL from this code used in a browser redirects to www.alotspace.com/error-404/ Just so you know.
Without testing, just looking at the code, I would start with checking the status line of the response. This is how
StatusLine statusLine = response.getStatusLine();
int statusCode = statusLine.getStatusCode();
if (statusCode == 200) {
// here all is OK, you can check for 404 and so on
}
Also I see you handling the response with a buffered reader putting everything in a StringBuilder further in code. A better alternative would be using gson.
But focus on the initial network related exception first. The other exceptions are just a result of the separate try/catch blocks (as #Snicolas pointed out already). Unknownhost sounds like no network. Being redirect would just return different output than expected, not unkownhost. To verify that browse to the url from your android device you're testing on.

Cannot bring data fro a URL using httpost request Android

I am having serious trouble on fetching my data from the server.
My url is this:
server_url = http://serverurl/_all
If I call that from my browser, I can see the data being printed. So I guess it has to do with how I make the request. I have used that part of code before, when making a post request for example in a php file. But now my server is setup differently and I know that the server works fine because I can fetch my data in the browser and in an IOS app.
I have tried this:
try {
HttpClient httpclient = new DefaultHttpClient();
#SuppressWarnings("deprecation")
//HttpPost httppost = new HttpPost(URLEncoder.encode(server_url));
HttpPost httppost = new HttpPost(server_url);
//httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
} catch (Exception e) {
Log.e("log_tag", "Error in http connection " + e.toString());
}
// convert response to string
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) {
sb.append(line + "\n");
}
is.close();
result = sb.toString();
System.out.println("Result:" + result);
} catch (Exception e) {
Log.e("log_tag", "Error converting result " + e.toString());
}
and I get this:
Result : Error 404 not found
Then, searching on the SO I have tried the following:
Remove the http://
change the HttpPost line into this
HttpPost httppost = new HttpPost(URLEncoder.encode(server_url));
In this case I get this error:
12-01 21:41:11.772: E/log_tag(28340): Error in http connection java.lang.IllegalStateException: Target host must not be null, or set in parameters. scheme=null, host=null, path=http://ec2-54-194-95-194.eu-west-1.compute.amazonaws.com/backend2/index.php/skicenter/_all
12-01 21:41:11.772: E/log_tag(28340): Error converting result java.lang.NullPointerException: lock == null
12-01 21:41:11.772: E/log_tag(28340): Error parsing data org.json.JSONException: End of input at character 0 of
There should be something wrong with the _ character os something else that I am missing.
Can you help me on that?
Are you sure, you are using the correct HTTP verb for the request? Maybe it's a GET request and you are trying with POST.

Chunked Steam error in android HTTP post

I'm working on creating an android app that will pull down user data from a MySQL database stored on a web server. I've read a few tutorials on HTTP Post that allows me to connect to the database, which I got working. However, I am unable to process the data that gets sent from the php.
The error I receive is: org.apache.http.MalformedChunkCodingException: Chunked stream ended unexpectedly.
This is the code I have written:
String name = username.getText().toString(); //username is a TextView field
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("user",name));
try
{
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(location);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpResponse response = httpclient.execute(httppost);
HttpEntity entity = response.getEntity();
is = entity.getContent();
}
catch(Exception e)
{
Toast.makeText(getBaseContext(), e.toString(), Toast.LENGTH_LONG).show();
Log.e("log_tag", "Error in http connection"+e.toString());
}
//Convert response to string
try
{
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null)
{
sb.append(line + "\n");
}
is.close();
result = sb.toString();
Log.i("log_tag", result);
}
catch(Exception e)
{
Toast.makeText(getBaseContext(),e.toString() ,Toast.LENGTH_LONG).show();
Log.e("log_tag", e.toString());
}
The error seems to appear in the convert response to string section. I've looked up several issues regarding similar errors to the one I received but what I read didn't seem to help much or I just don't know enough about http client coding...probably the latter. Any help would be greatly appreciated, thanks!
Here is the PHP as well:
<?php
$con = mysqli_connect("/**connection*/");
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: ".mysqli_connect_error();
}
$result = mysqli_query($con, "SELECT * FROM userNames WHERE user='".$_POST['name']."')";
if ($result == NULL)
{
die();
}
else
{
//TODO:get row to java
$rows = array();
while($r = mysql_fetch_assoc($result))
{
$rows[] = $r;
}
print json_encode($rows);
mysql_close();
}
mysqli_close($con);
}
?>
The end goal of this is to convert the JSON response from the database into separate variables, the buffered reader stuff is just a middle step before the JSON conversion. Again , I just followed a tutorial so if anyone knows a different way of going about this I'm open to suggestions.

Categories

Resources