I'm using a PHP script to access data in my database.
However, data transfer might be expensive if your plan doesn't cover 3G access. So if there's no Wifi around, it would be good to know, how much my application is actually downloading/uploading/using.
Is there a way I can determine how much Bytes I'm uploading (post arguments) and then downloading (string output/response of the php script)?
Code in use:
//http post
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(arguments));
HttpResponse httpresponse = httpclient.execute(httppost);
HttpEntity entity = httpresponse.getEntity();
is = entity.getContent();
Log.e("log_tag", "connection success ");
} catch(Exception e) {
Log.e("log_tag", "Error in http connection "+e.toString());
}
Use getEntity().getContentLength() to get the HTTP message size, in HTTP request and response. And save the consumed property in SharedPreferences to recover it in another session.
The code will look like:
static long consumed = 0;
//http post
long consumedNow = 0;
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
httppost.setEntity(new UrlEncodedFormEntity(arguments));
consumedNow += httppost.getEntity().getContentLength();
HttpResponse httpresponse = httpclient.execute(httppost);
HttpEntity entity = httpresponse.getEntity();
is = entity.getContent();
consumedNow += httpresponse.getEntity().getContentLength();
Log.e("log_tag", "connection success ");
} catch(Exception e) {
Log.e("log_tag", "Error in http connection "+e.toString());
} finally {
consumed += consumedNow;
SharedPreferences sp = context.getSharedPreferences("preferences", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sp.edit();
editor.putLong("consumed", value);
editor.commit();
}
Related
I have started to test http client apache API. I need it because I would like to send requests and to receive responses to virustotal API. Virus total API requires to parameters in the post request:
the api key value (a unique value for each user)
the file itself as I understood from their website.
For example:
>>> url = "https://www.virustotal.com/vtapi/v2/url/scan"
>>> parameters = {"url": "http://www.virustotal.com",
... "apikey": "-- YOUR API KEY --"}
>>> data = urllib.urlencode(parameters)
>>> req = urllib2.Request(url, data)
At the moment, I am trying to do the same thing in Java instead of Python. Here is a part of my source code commented to guide throughout the steps:
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
//create post request
HttpPost request = new HttpPost("https://www.virustotal.com/vtapi/v2/file/scan");
//http json header
request.addHeader("content-type", "application/json");
String str = gson.toJson(param);
String fileName = UUID.randomUUID().toString() + ".txt";
try {
//API key
StringEntity entity = new StringEntity(str);
Writer writer = new BufferedWriter(new FileWriter(fileName));
writer.write(VirusDefinitionTest.malware());
request.setEntity(entity);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
FileBody fileBody = new FileBody(new File(fileName));
builder.addTextBody("my_file", fileName);
HttpEntity entity = builder.build();
request.setEntity(entity);
HttpResponse response;
try {
response = httpClient.execute(request);
...
Unfortunately, I receive HTTP/1.1 403 Forbidden. Obviously, the error is somewhere in the entities but I cannot find how to do it. Any help would be deeply welcomed.
This worked for me with Apache 4.5.2 HttpClient:
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpPost httppost = new HttpPost("https://www.virustotal.com/vtapi/v2/file/scan");
FileBody bin = new FileBody(new File("... the file here ..."));
// the API key here
StringBody comment = new StringBody("5ec8de.....", ContentType.TEXT_PLAIN);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("apikey", comment)
.addPart("file", bin)
.build();
httppost.setEntity(reqEntity);
System.out.println("executing request " + httppost.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httppost);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
System.out.println("ToString:" + EntityUtils.toString(resEntity));
}
EntityUtils.consume(resEntity);
} finally {
response.close();
}
} finally {
httpclient.close();
}
The important part was the reqEntity which had to have two specifically named fields, "apikey", and "file". Running this with a valid API key gives me the expected response from the API.
The problem seems to be that first you add explicit "content-type" header which is "application/json" and at the end you send the Muiltipart entity. You need to add all the parameters and the file to the Muiltipart entity. Now the parameters are not send, because they are overwritten by Muiltipart entity:
CloseableHttpClient httpClient = HttpClientBuilder.create().build();
//create post request
HttpPost request = new HttpPost("https://www.virustotal.com/vtapi/v2/file/scan");
//http json header
request.addHeader("content-type", "application/json");
String str = gson.toJson(param);
String fileName = UUID.randomUUID().toString() + ".txt";
try {
//API key
StringEntity entity = new StringEntity(str);
Writer writer = new BufferedWriter(new FileWriter(fileName));
writer.write(VirusDefinitionTest.malware());
// --> You set parameters here !!!
request.setEntity(entity);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
FileBody fileBody = new FileBody(new File(fileName));
builder.addTextBody("my_file", fileName);
HttpEntity entity = builder.build();
// --> You overwrite the parameters here !!!
request.setEntity(entity);
HttpResponse response;
try {
response = httpClient.execute(request);
I have an app deployed on google app engine that uses the Apache HTTPClient. Recently as the app is getting more traffic, I have started running into exceptions where the sockets quota has been exceeded. The exception is
com.google.apphosting.api.ApiProxy$OverQuotaException: The API call remote_socket.SetSocketOptions() required more quota than is available.
I reached out to the App Engine team and they wanted me to check if my app was leaking sockets.
CloseableHttpClient httpclient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost("http://www.spark.com");
List <NameValuePair> nvps = new ArrayList <NameValuePair>();
nvps.add(new BasicNameValuePair("param1", "val1"));
nvps.add(new BasicNameValuePair("param2", "val2"));
httpPost.setEntity(new UrlEncodedFormEntity(nvps));
CloseableHttpResponse response = httpclient.execute(httpPost);
Document doc = null;
try {
HttpEntity entity = response.getEntity();
doc = Jsoup.parse(entity.getContent(), "UTF-8", "");
EntityUtils.consume(entity);
} finally {
response.close();
httpclient.close();
}
This is what my http connection code looks like. Am I doing something wrong which may be causing the sockets to leak? Can I do something better?
this work for me :
HttpParams httpParameters = new BasicHttpParams();
HttpProtocolParams.setContentCharset(httpParameters, HTTP.UTF_8);
HttpProtocolParams.setHttpElementCharset(httpParameters, HTTP.UTF_8);
HttpClient httpclient = new DefaultHttpClient(httpParameters);
// HttpPost httppost = new HttpPost("http://rafsanjan.uni-azad.my.com/json/darkhasr.php?shdaneshjo="+value_id+"&moavenat="+value_seaction+"&darkhast="+zir_item+"&startdate=test&tozih="+ value_descration); //???
try {
URIBuilder builder = new URIBuilder();
builder.setScheme("http")
.setHost("app.my.ac.com")
.setPort(1180)
.setPath("/json2/darkhasr.php")
.addParameter("shdaneshjo", value_id)
.addParameter("moavenat", value_seaction)
.addParameter("darkhast", value_item)
.addParameter("startdatet", "0")
.addParameter("tozih", value_descration)
.build();
// .fragment("section-name");
String myUrl = builder.toString();
Log.d("url=>",myUrl);
HttpPost httppost = new HttpPost(myUrl);
ArrayList<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(8);
//nameValuePairs.add(new BasicNameValuePair("name", name));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs,"UTF-8"));
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
Log.d("RESPONSE",EntityUtils.toString(resEntity));
}
catch(Exception e)
{
Log.e("log_tag", "Error: "+e.toString());
}
I have following situation:
Sending http post (post data contains json string) request to my remote server.
Getting http post response from my server in json: {"result":true}
Disconnecting all internet connections in my tablet.
Repeating post request described in step 1.
Getting the same cached "response" - {"result":true} which I didn't expected to get... I don't want that my http client would cache any data. I expect to get null or something like this.
How to prevent http client caching data?
My service handler looks like this:
public String makeServiceCall(String url, int method,
List<NameValuePair> params, String requestAction) {
try {
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpEntity httpEntity = null;
HttpResponse httpResponse = null;
// Checking http request method type
if (method == POST) {
HttpPost httpPost = new HttpPost(url);
// adding post params
if (params != null) {
httpPost.setEntity(new UrlEncodedFormEntity(params));
}
httpResponse = httpClient.execute(httpPost);
}
else if (method == GET) {
// appending params to url
if (params != null) {
String paramString = URLEncodedUtils
.format(params, "utf-8");
url += "?" + paramString;
}
HttpGet httpGet = new HttpGet(url);
httpResponse = httpClient.execute(httpGet);
}
httpEntity = httpResponse.getEntity();
response = EntityUtils.toString(httpEntity);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
// Toast.makeText(Globals.getContext(), "check your connection", Toast.LENGTH_SHORT).show();
}
return response;
}
I just noticed that response is a member variable. Why do you need a member variable to return this result. You're probably returning the same result on the 2nd try. Re-throw the exception that you catch instead and let the caller handle it.
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/
I have used php for server side and my client(A java program) sends a post request with json data as parameter. I am able to receive the data but the jsonData is no decoding. I am sending a valid JSON.
Below is my Client program.
public class ExampleHttpPost
{
public static void main(String args[]) throws ClientProtocolException, IOException
{
HttpPost httppost = new HttpPost("http://localhost/hello.php");
List<BasicNameValuePair> parameters = new ArrayList<BasicNameValuePair>();
try {
parameters.add(new BasicNameValuePair("data", (new JSONObject("{\"imei\":\"imei1\"}")).toString()));
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
httppost.setEntity(new UrlEncodedFormEntity(parameters));
HttpClient httpclient = new DefaultHttpClient();
HttpResponse httpResponse = httpclient.execute(httppost);
HttpEntity resEntity = httpResponse.getEntity();
// Get the HTTP Status Code
int statusCode = httpResponse.getStatusLine().getStatusCode();
// Get the contents of the response
InputStream input = resEntity.getContent();
String responseBody = IOUtils.toString(input);
input.close();
// Print the response code and message body
System.out.println("HTTP Status Code: "+statusCode);
System.out.println(responseBody);
}
}
And my hello.php
<?php
$data = $_POST['data'];
var_dump($data);
$obj = json_decode($data);
if($obj==NULL){
echo "Decoding error";
}
echo $obj['imei'];
?>
Output :
HTTP Status Code: 200
string(20) "{\"imei\":\"imei1\"}"
Decoding error
It seems like your Java Application is adding slashes to the string or as suggested in the comments the PHP app is probably adding slashes to the quotes to avoid SQL injection
Try if you can get it to work by adding
$data = stripslashes($data);
Above the json_decode part