Using HttpGet returning complete HTML code - android

I am trying to invoke a private web-service in which there's one link I've to access using GET method. While using the direct URL on browser (needs to login first), I get the data in JSON format. The URL I am invoking is like this
http://www.example.com/trip/details/860720?format=json
The url is working fine, but when I invoke this using HttpGet, I am getting the HTML coding of the webpage, instead of the JSON String. The code I am using is as follows:
private String runURL(String src,int id) { //src="http://www.example.com/trip/details/"
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet(src);
String responseBody="";
BasicHttpParams params=new BasicHttpParams();
params.setParameter("domain", token); //The access token I am getting after the Login
params.setParameter("format", "json");
params.setParameter("id", id);
try {
httpget.setParams(params);
HttpResponse response = httpclient.execute(httpget);
responseBody = EntityUtils.toString(response.getEntity());
Log.d("runURL", "response " + responseBody); //prints the complete HTML code of the web-page
} catch (Exception e) {
e.printStackTrace();
}
return responseBody;
}
Can you tell me what am I doing wrong here??

Try specify Accept & Content-Type in you http header:
httpget.setHeader("Accept", "application/json"); // or application/jsonrequest
httpget.setHeader("Content-Type", "application/json");
Note that you can use tools like wireshark capture and analyse the income and outcome http package, and figure out the exact style of the http header that returns your json response from a standard browser.
Update:
You mentioned need login first when using browser, the html content returned is probably the login page (if use basic authentication type, it returns a short html response with status code 401, so a modern browser knows how to handle, more specifically, pop up login prompt to user), so the first try would be checking the status code of your http response:
int responseStatusCode = response.getStatusLine().getStatusCode();
Depend on what kind of authentication type you use, you probably need specify login credentials in your http request as well, something like this (if it is a basic authentication):
httpClient.getCredentialsProvider().setCredentials(
new AuthScope("http://www.example.com/trip/details/860720?format=json", 80),
new UsernamePasswordCredentials("username", "password");

Related

How to use HTTP POST with "application/octet-stream" in Android? (Microsoft Cognitive Video)

I want to use the Video Cognitive Service in Android.
The sample that Microsoft provided is used in C#.
The video function is sending an URL to the server,
So I think it is possible using HTTP POST to send an URL in Android.
http://ppt.cc/V1piA
The problem I met is that I don't know the URL format in "application/octet-stream", and I didn't see the example on the Microsoft website.
Is it possible using HTTP POST in Android to upload a downloaded video to the server, and I can get the analysis result from the server?
If possible, what is the format of the HTTP POST to send request to the server?
Thanks.
You may try something like this to send image files for cognitive-services face detect.
Using org.apache.httpcomponents::httpclient :
#Test
public void testSendBinary() throws MalformedURLException {
File picfile = new File("app/sampledata/my_file.jpeg");
if (!picfile.exists()) throw new AssertionError();
HttpClient httpclient = HttpClients.createDefault();
try {
URIBuilder builder = new URIBuilder("https://westcentralus.api.cognitive.microsoft.com/face/v1.0/detect");
builder.setParameter("returnFaceId", "true");
builder.setParameter("returnFaceLandmarks", "false");
URI uri = builder.build();
HttpPost request = new HttpPost(uri);
request.setHeader("Content-Type", "application/octet-stream");
request.setHeader("Ocp-Apim-Subscription-Key", "***");
// Request body
request.setEntity(new FileEntity(picfile));
HttpResponse response = httpclient.execute(request);
HttpEntity entity = response.getEntity();
if (entity != null) {
System.out.println(EntityUtils.toString(entity));
}
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
HTTP POST refers to the HTTP method 'POST', application/octet-stream refers to the media type - in this case a stream of application specific octets or bytes.
This is, unfortunately, very subjective as the mechanism for uploading content via HTTP action may be preferred one way or another. Suffice it to say, you will create an InputStream of your content, format a POST request using the mechanism of your choosing:
straight Java
HTTPClient
Making sure to set the content-type of the POST to application/octet-stream.
After performing the post, consult your API documentation for expected return types.

how to send/POST JWT token from Android to Laravel backend

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;
}

http request to password protected files

The php files on my server are password protect with htaccess. How can I make request to these files through my android app?
I couldnt find any relevant answers with google search.
Here you can find your answer:
Basic HTTP Authentication on Android
Basically:
HttpUriRequest request = new HttpGet(YOUR_URL); // Or HttpPost(), depends on your needs
String credentials = YOUR_USERNAME + ":" + YOUR_PASSWORD;
String base64EncodedCredentials = Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
request.addHeader("Authorization", "Basic " + base64EncodedCredentials);
HttpClient httpclient = new DefaultHttpClient();
httpclient.execute(request);
// You'll need to handle the exceptions thrown by execute()
You can replace the last line with:
EDITED:
You can try someting like this:
try {
HttpResponse response = httpclient.execute(request);
//this is the login response, logged so you can see it - just use the second part of the log for anything you want to do with the data
Log.d("Login: Response", EntityUtils.toString(response.getEntity()));
} catch (IOException e) {
//if something went badly wrong
}
So you can view your response, maybe the problem is parsing the JSON.
Assuming your PHP files are protected by HTTP Basic Authentication, you can request your php files using this special URL syntax:
http://validuser:validpassword#www.domain.com/validfile.php

Android HttpPost request exception

Just as a demonstration the code will work, I am attempting to fetch some JSON data within my oncreate function. I know it should run on a different thread but I want to be sure the code successfully fetches my JSON before moving it into it's own thread.
The code is below:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_activity);
/***************************************************/
final String TAG = "PostFetcher";
final String SERVER_URL = "http://kylewbanks.com/rest/posts";
// final String TAG = "PostsActivity";
// List<Post> posts;
try {
//Create an HTTP client
HttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(SERVER_URL);
//Perform the request and check the status code
HttpResponse response = client.execute(post);
StatusLine statusLine = response.getStatusLine();
if(statusLine.getStatusCode() == 200) {
HttpEntity entity = response.getEntity();
InputStream content = entity.getContent();
try {
//Read the server response and attempt to parse it as JSON
Reader reader = new InputStreamReader(content);
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("M/d/yy hh:mm a");
Gson gson = gsonBuilder.create();
List<JsonObject> posts = new ArrayList<JsonObject>();
Log.e(TAG, "Checking: " + posts);
// posts = Arrays.asList(gson.fromJson(reader, JsonObject[].class));
content.close();
} catch (Exception ex) {
Log.e(TAG, "Failed to parse JSON due to: " + ex);
}
} else {
Log.e(TAG, "Server responded with status code: " + statusLine.getStatusCode());
}
} catch(Exception ex) {
Log.e(TAG, "Failed to send HTTP POST request due to: " + ex);
}
}
When I run the code, I get the second to last exception message:
Server responded with status code: 500
Can anyone please tell me what I'm doing wrong?
You are sending a HttpPost request to (obviously) an website that uses RESTful styled API.
This means, it works with HTTP Verbs (GET, POST, PUT, DELETE).
If you want to read data and the read access never changes data, use GET.
If you want to update or replace data, user PUT or POST (put usually to replace, POST to change/add). However, JavaScript does (or did) only support GET and POST requests, so keep that in mind.
If you want to delete a resource or collection, use DELETE.
That being said: If you want to load data, use Get in your case HttpGet instead of HttpPost.
Also read more about RESTful web APIs.
Edit:
In fact, calling the given URL in Fiddler2 (as stated in the comment on the other answer) results a HTML website reporting the error:
You called this URL via POST, but the URL doesn't end in a slash and
you have APPEND_SLASH set. Django can't redirect to the slash URL
while maintaining POST data. Change your form to point to
kylewbanks.com/rest/posts/ (note the trailing slash), or set
APPEND_SLASH=False in your Django settings.
Its internal server error..check if there are any exceptions are getting thrown at server side.
It has nothing to do with your android code, the problem is at server.
You can use AsyncTask to run network/filesystem related operations.

Send token with HTTP POST from android to cakephp

i am sending data from an android device to my cakephp website through HTTP Post in json object ..like this
HttpPost post = new HttpPost("https://www.mywebtest.com/test");
and then i decode the json and extract the data like this
if ($this->request->isPost()){
$json = $this->request->data('json');
$data = json_decode($json, TRUE);
but at the moment i am not checking that whether the http post or data is coming from my android app or someone else .so if someone knows the url he can do something malicious ..because at times now the url which i have written in httpPost when i typed this url in my browser there is nothing is shown on the browser.. i want to display some kind of error or 404 page if some one typed the url in browser.. Essentially, you can say i am creating with CakePHP is an API, What i want to do is secure the API so only my app can execute requests.so i want to implement some type of authentication .. doing some research i come up to a solution that pass another parameter as a secret token from android app and then check token from my webapp and then extract data .. i dont know how can i pass another parameter in httppost and then check it on my webpage .. and also if that possible i want to randomly generate the token and encrypt it on every request and then decrypt it through key in webapp whenever the data is posting from android to webapp.. if someone has done before this or have an idea then please share code or any link.
Create a JsonObject for parameters,
JSONObject parametersList = new JSONObject();
put your parameters into that JSONObject
parametersList.put("testID", 123);
int androidValue = 231231231; // a identifer or password your choice.
parametersList.put("androidValue", androidValue);
and add list to your HttpPost
HttpPost request = new HttpPost("https://www.mywebtest.com/test");
request.setHeader(HTTP.CONTENT_TYPE, "application/json; charset=utf-8");
request.setEntity(new StringEntity(parameters.toString(), HTTP.UTF_8));
On the php side;
<?php
$postdata = $HTTP_RAW_POST_DATA;
$data = json_decode($postdata);
$id = $data->testID;
$androidValue = $data->androidValue;
if(androidValue == 231231231)
{
$json = "{d:[{sample1:'".$id."',sample2:'value12'}]}";
$response = $_GET["callback"] . $json;
echo $response;
}
else
{
// send failed data
}
?>
And this how to get respond on android side
HttpResponse response = client.execute(request);
final int statusCode = response.getStatusLine().getStatusCode();
final String jsonResponse = EntityUtils.toString(response.getEntity());
if (statusCode != HttpStatus.SC_OK) {
Log.w(TAG, "Error in web request: " + statusCode);
Log.w(TAG, jsonResponse);
return null;
} else {
Log.i(TAG, jsonResponse);
return jsonResponse;
}
I hope this will help.
Try with RequestHandler isMobile().
You will get true, if request is from mobile phone.
http://book.cakephp.org/2.0/en/core-libraries/components/request-handling.html#RequestHandlerComponent::isMobile

Categories

Resources