I'm trying to simulate a process like "cache validation" in my application.
I will download a new version of my webapplication on the device (android-based), but I only want to download a new version of the files, based in a etag comparision.
Does anyone a example of how use the Etag mechanism in Android?
You can access the ETag field from a HttpURLConnection object such as like this:
HttpURLConnection conn = (HttpURLConnection)new URL(url).openConnection();
String etag = conn.getHeaderField("ETag");
Of course, you will need to make sure that the server you are testing this against supports ETags.
Maybe class "HttpRequest" from this library (kevinsawicki) will help you.
For example:
File latest = new File("/data/cache.json");
HttpRequest request = HttpRequest.get("http://google.com");
//Copy response to file
request.body(latest);
//Store eTag of response
String eTag = request.eTag();
//Later you can check if changes exist
boolean unchanged = HttpRequest.get("http://google.com")
.ifNoneMatch(eTag)
.notModified();
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
try {
HttpResponse response = httpClient.execute(httpPost);
Log.d("Http Response:", response.getFirstHeader("etag").toString());
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You can refer to the specific implement of ShallowEtagHeaderFilter performing etag generation and validation in Spring.
Related
Android HTTP PUT not sending JSON request to server resulting in HTTP 405 Method not allowed.
Below is my async task background code
HttpClient httpclient = new DefaultHttpClient();
HttpPut httpPut = new HttpPut("URL");
String jsonresponse = "";
try {
StringEntity se = new StringEntity(gson.toJson(resultPojo).toString());
se.setContentType("application/json;charset=UTF-8");//text/plain;charset=UTF-8
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE,"application/json;charset=UTF-8"));
httpPut.setEntity(se);
httpPut.setHeader("Accept", "application/json");
httpPut.setHeader("Content-type", "application/json");
HttpResponse response = httpclient.execute(httpPut);
HttpEntity httpEntity = response.getEntity();
jsonresponse = EntityUtils.toString(httpEntity);
System.out.println("res .... "+jsonresponse);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
serverside code :
#POST
#Path("{id}")
#Produces(MediaType.APPLICATION_JSON)
#Consumes(MediaType.APPLICATION_JSON)
public Response submitUserResponse(#PathParam("userId") int userId,
#PathParam("id") int id, List<ResultPojo> responses) {
try {
//core logic goes here
return Response.status(Response.Status.CREATED).build();
} catch (Exception e) {
e.printStackTrace();
return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
}
}
Alright just like what was discussed it is most likely a mismatch different HTTP methods, in this case A Put and a post, whenever you ever encounter that HTTP code(405) do perform a validation on the methods you used, it happens.405 errors often arise with the POST method. You may be trying to introduce some kind of input form on the Web site, but not all ISPs allow the POST method necessary to process the form.A request method is not supported for the requested resource; for example, a GET request on a form that requires data to be presented via POST, or a PUT request on a read-only resource.
i wanted to access my back-end using android phone. at this moment i want to do two things:
login the mob app after being authenticated from the Back-end.
Upload data to the back-end (back-end is PHP with Laravel Framework).
i first send email and password to the backend and gotten back a response of JWT token as shown:
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjEsImlzcyI6Imh0dHA6XC9cLzE5Mi4xNjguMS4xMDI6ODAwMFwvYXBpXC92M1wvYXV0aGVudGljYXRlIiwiaWF0IjoxNDY2MDA5OTY3LCJleHAiOjE0NjYwMTM1NjcsImp0aSI6IjZjYjBlMTRjYTNkMjAzM2Q4OWM0NzM1M2ZjNjMzZTU2In0.GJGUjgy8U-uqjLSqJcysDTmgrNvxBHH03iBflLjsOwA"
Once the above token returned to the mob app, i want to send the same returned token for further post request, because the above jwt token is my key for accessing the back-end.
So my problem lies on sending the same token back to the back-end. it seems simple and stright forward since i have already started to communicate with my back end, and i have also checked my response by using post man.
and i can also got the user cridential using the jwt token on postman.
now the same token which works on postman is not working for my android. i know that my httpClient and httpPost are working since i have already send the email and password with it. i also know that my android post request is reaching the server since my returned result comes with an error message i built for an accepted token request, as shown below.
as you can see from the above snap shot. i first get the token inside a quotation (first highlighted), when posted for authentication. so i removed the quotation and posted the same token for getting user cridential but this time i got an error response which i built it on the Back-end.
so that is why i think my token is not going to the server properly. but i couldn't fix the problem. but i am guessing the token size is big, with a length of 490. so how shall i attach my token with the httpPost request? my code for the building the request is shown below:
public String getJsonString2(String url, String jwtString) {
String jsonString = "";
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
List nameValuePair = new ArrayList(1);
nameValuePair.add(new BasicNameValuePair("token", jwtString));
try {
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePair));
}
catch (UnsupportedEncodingException e) {
// writing error to Log
e.printStackTrace();
}
// Making HTTP Request
try {
HttpResponse response = httpClient.execute(httpPost);
jsonString = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
} catch (ClientProtocolException e) {
// writing exception to log
e.printStackTrace();
} catch (IOException e) {
// writing exception to log
e.printStackTrace();
}
return jsonString;
}
i have also tried using MultipartEntityBuilder for parsing the parameter (token in my case) but the MultipartEnityBuilder library was crasshing my program when building:
the MultipartEnityBuilder library is added to my project using the following dependencies:
//for accessing the MultipartEntity lbrary
compile "org.apache.httpcomponents:httpcore:4.2.4"
compile "org.apache.httpcomponents:httpmime:4.3"
the error because of the MultipartEntity
So now my question is:
how can i send the jwt token value from android to Laravel backend.
Perhaps try using MultipartEntity instead and create a "part" for the token. I have adapted this closely related answer to your case:
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);
//here you create the token body
MultipartEntityBuilder builder = MultipartEntityBuilder.create();
builder.addTextBody("token", jwtString, ContentType.TEXT_PLAIN);
HttpEntity reqEntity = builder.build();
httppost.setEntity(reqEntity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
I hope this helps, please give it a try and let me know.
You can visit this blog on Multipart Upload with HttpClient and learn more.
i have managed to solve my problem by simply setting the Authorization header with the token:
public String getJsonString2(String url, String jwtString) {
String jsonString = "";
// Creating HTTP client and post
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Authorization", "Bearer \\{" + jwtString + "\\}");
// Making HTTP Request
try {
HttpResponse response = httpClient.execute(httpPost);
jsonString = EntityUtils.toString(response.getEntity(), HTTP.UTF_8);
System.out.println("Http String content: " + jsonString);
} catch (ClientProtocolException e) {
// writing exception to log
e.printStackTrace();
} catch (IOException e) {
// writing exception to log
e.printStackTrace();
}
return jsonString;
}
I have been using this code to get JSON from a specified URL, but today I checked it, and everything in it is deprecated. It still works fine, but I want to know what is the new method of doing it?
Here's what I have:
#Override
protected String doInBackground(String... params) {
try {
HttpClient client = new DefaultHttpClient();
StringBuilder url = new StringBuilder("some url");
HttpGet hg = new HttpGet(url.toString());
HttpResponse hr = client.execute(hg);
int status = hr.getStatusLine().getStatusCode();
if (status == 200) {
HttpEntity he = hr.getEntity();
String data = EntityUtils.toString(he);
jsonGet = new JSONObject(data);
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
The deprecated objects are HttpClient, HttpGet, HttpResponse, HttpEntity and EntityUtils.
EDIT: As suggested in some questions, this way
HttpClient client = HttpClientBuilder.create().build();
does not work for me, as I am getting HttpClientBuilder cannot be resolved
Apache httpClient is deprecated with api level 22 you can read it about this blog.
there is a new client for android now and it is very good.
but you can use okhttp instead (also back compat is possible).
EDIT
check this link(URL.openConnection()). this blog was posted in 2011 but they mentioned the deprecation there first as far as i know.
First of all you have to search well on Google.
Here is your answer may it will helps you.
The HttpClient documentation points you in the right direction:
org.apache.http.client.HttpClient:
This interface was deprecated in API level 22.
Please use openConnection() instead. Please visit this webpage for further details.
means that you should switch to java.net.URL.openConnection().
Here's how you could do it:
URL url = new URL("http://some-server");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
// read the response
System.out.println("Response Code: " + conn.getResponseCode());
InputStream in = new BufferedInputStream(conn.getInputStream());
String response = org.apache.commons.io.IOUtils.toString(in, "UTF-8");
System.out.println(response);
IOUtils documentation: Apache Commons IO
IOUtils Maven dependency: http://search.maven.org/#artifactdetails|org.apache.commons|commons-io|1.3.2|jar
Special Thanks to fateddy for this answer
In my application, I am trying to hit a URL which I do using the following code
try {
url = new URL(serverURL);
httpURLConnection = (HttpURLConnection) url.openConnection();
int timeout = 30000;
httpURLConnection.setConnectTimeout(timeout);
httpURLConnection.setReadTimeout(timeout);
httpURLConnection.connect();
String httpResponseMessage = httpURLConnection.getResponseMessage();
responseCode = httpURLConnection.getResponseCode();
Log.i(LOG_TAG,"Response code "+responseCode);
} catch (Exception e) {
e.printStackTrace();
}
The (confidential) URL when opened through browser (on computer as well as on phone), works perfectly and the response is as expected. But when I hit the same URL via the above piece of code, it gives me response code 404 (NOT FOUND). Can anybody tell me what the issue can be?
(Sorry, can not post the URL since is highly confidential.)
Are you sure that you have the android.permission.INTERNET declared in your AndroidManifext.xml?
Problem solved :)
try {
url = new URL(serverURL);
Log.i(LOG_TAG, url+"");
HttpGet method= new HttpGet(new URI(serverURL));
HttpClient client = new DefaultHttpClient();
HttpGet request = new HttpGet();
request.setURI(new URI(serverURL));
HttpResponse response = client.execute(method);
responseCode = response.getStatusLine().getStatusCode();
Log.i(LOG_TAG,"Response code response "+response);
Log.i(LOG_TAG,"Response responseCode "+responseCode);
} catch (Exception e) {
e.printStackTrace();
}
Actually you don't even need following two lines in your code.
HttpGet request = new HttpGet();
request.setURI(new URI(serverURL));
One HttpGet is enough and you don't need it twice.
Not sure if this matters but I had the exact problem.
I was doing some explicity port 80 stuff and removing this line made it work:
HttpHost host = new HttpHost(targetHost, 80, "http");
I am trying to send data to my server using HttpPost via the following code.
private boolean FacebookLogin(String url) {
boolean isDataSend = false;
try {
HttpClient client = new DefaultHttpClient();
HttpPost request = new HttpPost(url);
List<NameValuePair> value = new ArrayList<NameValuePair>();
value.add(new BasicNameValuePair("data", FacebookData()));
UrlEncodedFormEntity entity = new UrlEncodedFormEntity(value);
request.setEntity(entity);
HttpResponse res = client.execute(request);
if (res.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String bufstring = EntityUtils.toString(res.getEntity(),
"UTF-8");
isDataSend = true;
}
} catch (Exception e) {
}
return isDataSend;
}
Is there any way i can have a look at how the $_POST looks on the server end. so that it will be easier for me to code the server part.
You can write the received $_POST on a file. Sometimes I do that. It's not the most elegant solution, but it works fine.
Try using a http proxy (e.g. Fiddler) for debugging, it helps a lot in these cases. You can set up an emulator to use this proxy for network communications, so you can inspect the messages sent and received. Check out the emulator docs on how to configure it to use a proxy.