How to cache the response of Http Client in Android App? - android

In my android application I am trying to cache the response of Http Client
The console always shows the "The response came from an upstream server" message when I call the url.
My code for Http Client is as follows:
try
{
CacheConfig cacheConfig = new CacheConfig();
cacheConfig.setMaxCacheEntries(1000);
cacheConfig.setMaxObjectSizeBytes(8192);
DefaultHttpClient realClient = new DefaultHttpClient();
realClient.addResponseInterceptor(MakeCacheable.INSTANCE, 0); // This goes first
CachingHttpClient httpClient = new CachingHttpClient(realClient, cacheConfig);
HttpContext localContext = new BasicHttpContext();
String requestUrl= SERVER_IP+ ANDROID_REQUEST_URL+METHOD_GET_ALLDEALS;
HttpPost httppost = new HttpPost(requestUrl);
ArrayList<NameValuePair> nameValuePairs=new ArrayList<NameValuePair>();
BasicNameValuePair latitudeValue=new BasicNameValuePair("lat",String.valueOf(28.460190279993547));
BasicNameValuePair longitudeValue=new BasicNameValuePair("lng",String.valueOf(77.0645221799944));
BasicNameValuePair radiusValue=new BasicNameValuePair("radius",String.valueOf(10));
BasicNameValuePair catIdValue=new BasicNameValuePair("cat",String.valueOf(1));
BasicNameValuePair subCategoryIdValue=new BasicNameValuePair("subcat",String.valueOf(0));
BasicNameValuePair offsetValue=new BasicNameValuePair("offset",String.valueOf(0));
BasicNameValuePair deviceIdvalue=new BasicNameValuePair("deviceId","12366A4C-9CD0-47F4-9ACC-D1CD7DD997FC");
BasicNameValuePair sessionIdValue=new BasicNameValuePair("sessionId","10873");
nameValuePairs.add(latitudeValue);
nameValuePairs.add(longitudeValue);
nameValuePairs.add(radiusValue);
nameValuePairs.add(catIdValue);
nameValuePairs.add(subCategoryIdValue);
nameValuePairs.add(offsetValue);
nameValuePairs.add(deviceIdvalue);
nameValuePairs.add(sessionIdValue);
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
String paramString = URLEncodedUtils.format(nameValuePairs,"utf-8");
String url = requestUrl+"?"+paramString;
HttpGet httpget = new HttpGet(url);
HttpResponse response = httpClient.execute(httpget,localContext);
HttpEntity entity = response.getEntity();
if (entity != null) {
InputStream instream = entity.getContent();
result = readIncomingData(instream);
instream.close();
Log.i("MainActivity", result);
}
CacheResponseStatus responseStatus = (CacheResponseStatus) localContext.getAttribute(
CachingHttpClient.CACHE_RESPONSE_STATUS);
switch (responseStatus) {
case CACHE_HIT:
Log.e("","A response was generated from the cache with no requests " +
"sent upstream");
break;
case CACHE_MODULE_RESPONSE:
Log.e("","The response was generated directly by the caching module");
break;
case CACHE_MISS:
Log.e("","The response came from an upstream server");
break;
case VALIDATED:
Log.e("","The response was generated from the cache after validating " +
"the entry with the origin server");
break;
}
}catch (Exception e) {
Log.i("MainActivity",e.getMessage());
}

I use the following block of code and call it in onCreate()
private void enableHttpResponseCache() {
try {
long httpCacheSize = 10 * 1024 * 1024; // 10 MiB
File httpCacheDir = new File(getCacheDir(), "http");
Class.forName("android.net.http.HttpResponseCache")
.getMethod("install", File.class, long.class)
.invoke(null, httpCacheDir, httpCacheSize);
Log.i(LOGTAG,"cache");
} catch (Exception httpResponseCacheNotAvailable) {
Log.i(LOGTAG,"nocache");
}
}
Bear in mind this will only enable caching on 4.0+ devices. Any lower than that and you will see "nocache" in the logs.

Related

Android HTTP POST request sent from application but server "sees" it as a GET request

I am sending some information to a sever for a university project of mine. The problem i am having is that the sever will only acpect POST request, it will not parse GET requests which is fair enough.
The issue i am having is that i am sending a httpPost request i check this using the built in Android method (see below) but when it arrives at the server it sees it as a GET request.
Post code:
JSONObject auth = new JSONObject();
auth.put("TEST", "TESTING");
HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost("http://xxxxxxxxxxxxx/upload.php");
String meth = httpPost.getMethod();
Toast checker = Toast.makeText(this, meth, Toast.LENGTH_LONG);
checker.show();
String json = "";
json = auth.toString();
StringEntity se = new StringEntity(json);
httpPost.setHeader("User-Agent", "android app");
httpPost.setEntity(se);
httpclient.execute(httpPost);
The check Toast, displays the value POST, which is correct.
The sever log shows this as a GET request.
xxxxxxxxxxx MY IP - - [09/Dec/2013:00:20:57 +0000] "GET /upload.php HTTP/1.1" 405 352 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:25.0) Gecko/20100101 Firefox/25.0"
Edited severname / Ip's out of the log and code.
ANy ideas?
Use this method my friend for posting data to server
public Boolean postDataWithURL(String url, String fileUrl,
ArrayList<NameValuePair> listParamsWithValues) {
boolean result = false;
try {
int TIMEOUT_MILLISEC = 100000; // = 10 seconds
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams,
TIMEOUT_MILLISEC);
HttpConnectionParams.setSoTimeout(httpParams, TIMEOUT_MILLISEC);
HttpClient client = new DefaultHttpClient(httpParams);
HttpPost request = new HttpPost(url);
if (fileUrl.equalsIgnoreCase("")) {
request.setEntity(new UrlEncodedFormEntity(listParamsWithValues));
} else {
// System.out.println("file path "+fileUrl+" with actual path "+file);
}
// request.setEntity(new
// ByteArrayEntity(listParamsWithValues.toString().getBytes("UTF8")));
HttpResponse response = client.execute(request);
String responseString = request(response);
// System.out.println(responseString);
if (responseString.toLowerCase().contains("1")) {
result = true;
} else {
result = false;
}
} catch (Exception e) {
// Some things goes Wrong
e.printStackTrace();
}
return result;
}

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 httpclient request and processing with entity

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.

Error using HTTP Post

I got an error using HttpPost for sending an MMS in Android.
In the Logcat it says:
ERROR/Here(447): ---------Error-----Target host must not be null, or set in parameters.
My sample code:
String url = "myurl";
HttpClient httpClient = new DefaultHttpClient();
try {
httpClient.getParams().setParameter(url, new Integer(90000)); // 90 second
HttpPost post = new HttpPost(url);
File SDCard = Environment.getExternalStorageDirectory();
File file = new File(SDCard, "1.png");
FileEntity entity;
entity = new FileEntity(file,"binary/octet-stream");
entity.setChunked(true);
post.setEntity(entity);
post.addHeader("Header", "UniqueName");
Log.i("MMSHTTP","----post---------------"+post);
HttpResponse response = httpClient.execute(post);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
Log.e("Here",
"--------Error--------Response Status line code:" + response.getStatusLine());
}
else
{
// Here every thing is fine.
}
HttpEntity resEntity = response.getEntity();
if (resEntity == null) {
Log.e("Here","---------Error No Response!!-----");
}
} catch (Exception ex) {
Log.e("Here","---------Error-----"+ex.getMessage());
ex.printStackTrace();
} finally {
httpClient.getConnectionManager().shutdown();
}
How do I fix the error?
The url you're specifying is in your sample code is:
String url = "myurl";
In order for HttpClient to be able to determine the host name, you're going to need to supply a valid url. Something along the lines of:
String url = "http://myurl.com/index";
Note: The 'http://' is important so that the appropriate protocol can be determined.
This guy had the same problem.

IIS seems to think an Android HttpPost is a GET

UPDATE: These problems were caused by a reverse proxy performing a 301 redirect. Altering the url to the destination of the redirect fixed the issue.
I am struggling to make a POST request from android to a web service.
I have a web service running on IIS7 with the following:
<OperationContract()> _
<Web.WebInvoke(BodyStyle:=WebMessageBodyStyle.Bare, Method:="POST", RequestFormat:=WebMessageFormat.Xml, ResponseFormat:=WebMessageFormat.Xml, UriTemplate:="HelloWorld")> _
Function HelloWorld() As XmlElement
When I send a POST request to this url from Firefox it works as expected.
When I make the request from an Android device using the following code:
String sRequest = "http://www.myserviceurl.com/mysevice/HelloWorld";
ArrayList<NameValuePair> arrValues = new ArrayList<NameValuePair>();
arrValues.add(new BasicNameValuePair("hello", "world"));
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpRequest = new HttpPost(sRequest);
httpRequest.setHeader("Content-Type", "application/x-www-form-urlencoded");
httpRequest.setEntity(new UrlEncodedFormEntity(arrValues));
HttpResponse response = httpClient.execute(httpRequest);
I get a Method Not Allowed 405 response and when looking in the IIS logs the request to this url appears as a "GET".
If I change the target of the request to a PHP script that echoes $_SERVER['REQUEST_METHOD'] the output is POST.
The web.config of the web service has GET, HEAD and POST as verbs.
Is there something I have overlooked?
I had to implement a workaround by disabling the automatic redirect and then catching the response code and redirect URL and reexecuting the POST.
// return false so that no automatic redirect occurrs
httpClient.setRedirectHandler(new DefaultRedirectHandler()
{
#Override
public boolean isRedirectRequested(HttpResponse response, HttpContext context)
{
return false;
}
});
Then when I issued the request
response = httpClient.execute(httpPost, localContext);
int code = response.getStatusLine().getStatusCode();
// if the server responded to the POST with a redirect, get the URL and reexecute the POST
if (code == 302 || code == 301)
{
httpPost.setURI(new URI(response.getHeaders("Location")[0].getValue()));
response = httpClient.execute(httpPost, localContext);
}
try:
DefaultHttpClient http = new DefaultHttpClient();
HttpResponse res;
try {
HttpPost httpost = new HttpPost(s);
httpost.setEntity(new UrlEncodedFormEntity(nvps, HTTP.DEFAULT_CONTENT_CHARSET));
res = http.execute(httpost);
InputStream is = res.getEntity().getContent();
BufferedInputStream bis = new BufferedInputStream(is);
ByteArrayBuffer baf = new ByteArrayBuffer(50);
int current = 0;
while((current = bis.read()) != -1){
baf.append((byte)current);
}
res = null;
httpost = null;
String ret = new String(baf.toByteArray(),encoding);
return ret;
}
catch (ClientProtocolException e) {
// TODO Auto-generated catch block
return e.getMessage();
}
catch (IOException e) {
// TODO Auto-generated catch block
return e.getMessage();
}

Categories

Resources