Downloading and parsing JSON on Android - android

I just want to ask what is the proper way of converting this into android code using HTTP get..
Basically I need to login to the website and do some specific search...
This is the actual code I have a problem with:
curl -H "Content-type: application/json" --basic --user "username:passowrd" -X GET -G \
--data-urlencode "status=triggered" \
--data-urlencode "assigned_to_user="\
"https://yourdomain.pagerduty.com/api/v1/incidents"
I am not sure if I can do that using put..
Example:
object.put("--data-urlencode", status=triggered)
and also for the username and password I am not sure if I can also do something like this
object.put("username", "romel");
object.put("password", "passwd");

If you are having HTTP Basic Auth problems, try this code to set your username and password...
HttpURLConnection con;
String basicAuthUsername = "username";
String basicAuthPassword = "passowrd"; //do you have a typo here??
try {
URL url = new URL(urlString);
con = (HttpURLConnection)url.openConnection();
if (basicAuthUsername != null && basicAuthPassword != null) {
String userAndPass = new StringBuilder(basicAuthUsername).append(":").append(basicAuthPassword).toString();
con.setRequestProperty("Authorization", "Basic " + Base64.encodeToString(userAndPass.getBytes(), Base64.NO_WRAP));
}
//con.setRequestMethod("POST");
con.setRequestMethod("GET");
con.setUseCaches(false);
int responseCode = con.getResponseCode();
//etc...
}
finally {
//close con, etc.
}
...also, maybe you have mistyped your password??

Your question isn't too detailed so I'm entirely sure what you're looking for - is it an authentication problem or JSON in general?
Handling JSON in Android is pretty well covered in a few places, including Vogella's tutorial.
Writing JSON is pretty easy, as in Vogella's example:
public void writeJSON() {
JSONObject object = new JSONObject();
try {
object.put("name", "Jack Hack");
object.put("score", new Integer(200));
object.put("current", new Double(152.32));
object.put("nickname", "Hacker");
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println(object);
}
Headers for things like content type are easy to add on your HTTPGet object as well, for example:
HttpGet httpGet = new HttpGet(API_URL);
httpGet.setHeader("Accept", "application/json");
httpGet.setHeader("Content-type", "application/json");
These are only snippets, use the tutorial linked above for a better, fuller explanation. Hope this helps.

Related

how to use URL to post data with HttpClient in android

I have to send/post some data to .svc Web Service that basically connect to remote database. I'm using JSONStringer to send the data but every time response status is false. My data is not sent. How to use HttpPost in Android . Can someone help me how to solve this .
Here is my webservice code
String namespace = "http://103.24.4.60/xxxxx/MobileService.svc";
public void ActivityUpload( final String strCurrentDateTime, final String strTitle, final String replaceDescChar, final String editedHashTag)
{
new AsyncTask<String, Void, String>()
{
#Override
protected String doInBackground(String... arg0)
{
String line = "";
try
{
Log.e("ActionDate "," = "+ strCurrentDateTime);
Log.e("ActivityId"," = "+strActivityId);
Log.e("UserId"," = "+str_UserId);
Log.e("ObjectId"," = "+strVessId);
Log.e("Name"," = "+strTitle);
Log.e("Remark"," = "+replaceDescChar);
Log.e("Status"," = "+"PENDING");
Log.e("Type"," = "+strType);
Log.e("starflag"," = "+0);
Log.e("HashTag"," = "+editedHashTag);
Log.e("Authentication_Token"," = "+str_Authentication_Token);
// make web service connection
HttpPost request = new HttpPost(namespace + "/Upd_Post_Activity");
request.setHeader("Accept", "application/json");
request.setHeader("Content-type", "application/json");
// Build JSON string
JSONStringer TestApp = new JSONStringer().object()
.key("ActionDate").value(strCurrentDateTime)
.key("ActivityId").value(strActivityId)
.key("UserId").value(str_UserId)
.key("ObjectId").value(strVessId)
.key("Name").value(strTitle)
.key("Remark").value(replaceDescChar)
.key("Status").value("PENDING")
.key("Type").value(strType)
.key("starflag").value("0")
.key("HashTag").value(editedHashTag)
.key("Authentication_Token").value(str_Authentication_Token).endObject();
StringEntity entity = new StringEntity(TestApp.toString());
Log.d("****Parameter Input****", "Testing:" + TestApp);
request.setEntity(entity);
// Send request to WCF service
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(request);
Log.d("WebInvoke", "Saving: " + response.getStatusLine().toString());
// Get the status of web service
BufferedReader rd = new BufferedReader(new InputStreamReader(
response.getEntity().getContent()));
// print status in log
while ((line = rd.readLine()) != null) {
Log.d("****Status Line***", "Webservice: " + line);
}
} catch (Exception e) {
e.printStackTrace();
}
return line;
}
}.execute();
}
Here is input Parameter.
****Parameter Input****﹕ Testing:{"ActionDate":"2016-01-21%2014:20:43%20PM","ActivityId":"120160119180421058","UserId":"125","ObjectId":"1","Name":"Title2","Remark":"Test%20two","Status":"PENDING","Type":"3","starflag":"0","HashTag":"990075","Authentication_Token":"6321D079-5B28-4F3F-AEE7-D59A1B9EFA59"}
Thanks in advanced.
realize android httpclients are in process of deprecation ( in favor of httpsurlconnection ) but, these httpclients are still used pretty widely. On gradle builds, regard the deprication, and with small dependency lib tweeks , httpclient may be used for some time still.
( still gonna use httpclient ? )
Put android aside for a min.
learn how to CURL with JSON body for tests that show you what you EXACT JSON in body and exact HEADERS you will need to get success http result to a post ... ref here
Once you have that you can then go about transferring your curl test's components over to android.httpclient.exec.POST using httpclient of your choice.
Set the same group of Headers you had over in curl tests in your android post. apache.httpclient sample
2.a. make sure that default list of headers from the clients 'request' constructor does NOT include by default some headers you DO NOT want... In order to assure of this ,you probably will need to turn on HEADER logging for your client.... java example logger . remove unnecessary headers included by the framework constructor of POST.
2.b android logger (WIRE, HEADERS) is diff from and may take some digging , depend on what client is in use.
with the same headers as curl tests, set the http.posts request.entity to either a string or a properly encoded array of bytes containing the same JSON body used in the curl tests.
3.A. depending on the JSON lib, create your message objects and then convert the objects to some friendly type for enclosure in an entity for the post ie use a 'writer' to convert objects to a serialized string with the JSON.
reqRole = new ObjectMapper().createObjectNode();
reqRole.put("__type", "Pointer");
reqRole.put("className", "_Role");
reqRole.put("objectId", roleId);
rootOb.put("requestedRole", reqRole);
rootOb.put("requestedBy",usersArr);
StringWriter writer = new StringWriter();
try {
new ObjectMapper().writeValue(writer, rootOb)
..
String http-post-str=writer.toString();
3.B. wrap the string with json in the POST request...
httpPost.setEntity(new StringEntityHC4(http-post-str));
exec the request and youll get the same results you got in curl because the headers are same or nearly same and the body is the same , encoded string of json. same input = same result

Android send https post request to the server without deprecated methods

In my app is used send request by https by following this source answer. Now some of them apache methods deprecated. Can anyone help me in order solve in a new approach?
To avoid using deprecated methods in API connectivity, think about using Retrofit. It's a third party library which makes HTTP communication much simpler.
When using Retrofit, you can create an interface of an API endpoint and the use it like a method. The rest of the HTTP request is managed by the library.
Here is the link to the Retrofit github homepage:
http://square.github.io/retrofit/
HttpURLConnection is part of SDK from API 1, you can use same http://developer.android.com/reference/java/net/HttpURLConnection.html.
// HTTP POST request
private void sendPost() throws Exception {
//Your server URL
String url = "https://selfsolve.apple.com/wcResults.do";
URL obj = new URL(url);
HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();
//add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
//Request Parameters you want to send
String urlParameters = "sn=C02G8416DRJM&cn=&locale=&caller=&num=12345";
// Send post request
con.setDoOutput(true);// Should be part of code only for .Net web-services else no need for PHP
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Post parameters : " + urlParameters);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
in.close();
//print result
System.out.println(response.toString());
}
More details you can get from
http://www.mkyong.com/java/how-to-send-http-request-getpost-in-java/
http://syntx.io/how-to-send-an-http-request-from-android-using-httpurlconnection/
Please check the below function:
public String makeServiceCall(String url1, MultipartEntity reqEntity) {
try {
// http client
URL url= new URL(url1);
HttpURLConnection httpClient = (HttpURLConnection) url.openConnection();
httpClient.setRequestMethod("POST");
httpClient.setUseCaches(false);
httpClient.setDoInput(true);
httpClient.setDoOutput(true);
httpClient.setRequestProperty("Connection", "Keep-Alive");
httpClient.addRequestProperty("Content-length", reqEntity.getContentLength()+"");
OutputStream os = httpClient.getOutputStream();
reqEntity.writeTo(httpClient.getOutputStream());
os.close();
httpClient.connect();
if (httpClient.getResponseCode() == HttpURLConnection.HTTP_OK) {
return readStream(httpClient.getInputStream());
}
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
In Android SDK 23
HttpClient is deprecated, you can migrate your code in HttpURLConnection
Something like this
URL url = new URL(urlString);
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setDoInput(true);
connection.connect();
if u want to continue using HttpClient for API level 22 and 23..
add org.apache.http.legacy.jar in ur project's Lib folder,
ull get .jar file in Android\sdk\platforms\android-23\optional..
if ur using android studio, after copy pasting jar file in lib folder,right click on jar file and click add as library
ur problem will be solved..comment if need any help.
thanx!
You can Use this Method for Get or Post Any purpose. Just use this method for Server request.
public void RequestToServer() {
// String User_id = "h";
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
// params.put("uid", User_id.toString());
client.post("http:// Your Url", params, new AsyncHttpResponseHandler() {
#Override
public void onSuccess(String s) {
super.onSuccess(s);
Log.d("Server Response for success :", s);
tv.append("service_ReloadSqlDB" + " " + s);
}
#Override
public void onFailure(Throwable throwable) {
super.onFailure(throwable);
Log.d("Server Response for onFailure ", throwable.toString());
}
});
}
You also need a jar file = android-async-http-1.3.1.jar
download this jar and add your android project in libs folder
After that add this in your build.gradle
dependencies {
compile files('libs/<android-async-http-1.3.1.jar>')
}
Finally rebuild your project , run the application , Get your Server response.

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

calling RESTful WCFservice method with object as parameter from java

i have a RESTful WCF service and one of its methods use an Object as parameter
[WebInvoke(UriTemplate = "save", Method = "POST", RequestFormat = WebMessageFormat.Xml, ResponseFormat= WebMessageFormat.Xml), OperationContract]
public SampleItem Create(SampleItem instance)
{
return new SampleItem() { Id = 1, StringValue = "saved" };
// TODO: Add the new instance of SampleItem to the collection
//throw new NotImplementedException();
}
I am trying to call this method from my eclipse android project. i am using these lines of codes
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpPost post=new HttpPost("http://10.0.2.2:2768/Service1.svc/save");
ArrayList<NameValuePair> nvp= new ArrayList<NameValuePair>();
nvp.add(new BasicNameValuePair("Id", "1"));
nvp.add(new BasicNameValuePair("StringValue", "yolo"));
post.setEntity(new UrlEncodedFormEntity(nvp));
HttpResponse httpResponse = httpClient.execute(post);
HttpEntity httpEntity = httpResponse.getEntity();
String xml = EntityUtils.toString(httpEntity);
Every time i get this error Method not allowed. in the XML that is returned by the service method.
i have tried invoking it from the browser, but encountered the same error there.
please tell me what i am doing wrong and what i can do instead.
thanks in advance to anyone who can help.
note: other methods which do not use object as parameter are working fine.
EDIT: tried Fiddler2 with success. but stalled again.
i have tried invoking the method SampleItem Create(SampleItem instance) with the url http://localhost:2768/Service1.svc/save and it works. the method returns the object in XML format.
in fiddler i added the request body as
<SampleItem xmlns="http://schemas.datacontract.org/2004/07/WcfRestService1" xmlns:i="http://www.w3.org/2001/XMLSchema-instance"><Id>1</Id><StringValue>saved</StringValue></SampleItem>
but the problem is that i can not find any way to add this xml string to the HttpPost or HttpRequest as the requestbody eclipse android project.
note: passing the xml string as Header or UrlEncodedFormEntity did not work.
finally i have succeeded to send a json object over to my WCF Service here's my code
URI uri = new URI("http://esimsol.com/droidservice/pigeonlibrary.service1.svc/save");
JSONObject jo1 = new JSONObject();
jo1.put("Id", "4");
jo1.put("StringValue", "yollo");
HttpURLConnection conn = (HttpURLConnection) uri.toURL().openConnection();
conn.setRequestProperty("Content-Type","application/json; charset=utf-8");
conn.setRequestProperty("Accept", "application/json");
conn.setRequestProperty("User-Agent", "Pigeon");
conn.setChunkedStreamingMode(0);
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.connect();
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.write(jo1.toString().getBytes());
out.flush();
int code = conn.getResponseCode();
String message = conn.getResponseMessage();
InputStream in = conn.getInputStream();
StringBuffer sb = new StringBuffer();
String reply;
try {
int chr;
while ((chr = in.read()) != -1) {
sb.append((char) chr);
}
reply = sb.toString();
} finally {
in.close();
}
SampleItem SI = new SampleItem();
SI=new Gson().fromJson(reply, SampleItem.class);
Toast.makeText(getApplicationContext(), SI.getStringValue(),Toast.LENGTH_LONG).show();
conn.disconnect();
thanks to StackOverFlow.
i had to combine a number of code snippets to achieve this.
First, you should get the Web Service method working from the browser - I recommend using Fiddler2 - its easier to construct the request body with your object and also to set the request headers when doing a post. It will show you the response so should help with debugging.
As for your code, I'm doing a POST to a WCF service and instead of doing
post.setEntity(new UrlEncodedFormEntity(nvp));
I'm simply doing:
HttpPost request = new HttpPost(url);
// Add headers.
for(NameValuePair h : headers)
{
request.addHeader(h.getName(), h.getValue());
}
(I am using JSONObjects and I have RequestFormat = WebMessageFormat.Json in my WebInvoke parameters.
Also, check your using the correct UriTemplate name in your url as they are case sensitive.
To call that WCF service you must build valid SOAP request and post it. It is better to use some SOAP protocol stack on Android - for example kSoap2.
Here is example of using kSoap2 to call WCF service.
just add KSOAP2 lib in your project.for how we add KSOAP2 in Android project see this post

Sending HTTP DELETE request in Android

My client's API specifies that to remove an object, a DELETE request must be sent, containing Json header data describing the content. Effectively it's the same call as adding an object, which is done via POST. This works fine, the guts of my code is below:
HttpURLConnection con = (HttpURLConnection)myurl.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setUseCaches(false);
con.connect();
OutputStreamWriter wr = new OutputStreamWriter(con.getOutputStream());
wr.write(data); // data is the post data to send
wr.flush();
To send the delete request, I changed the request method to "DELETE" accordingly. However I get the following error:
java.net.ProtocolException: DELETE does not support writing
So, my question is, how do I send a DELETE request containing header data from Android? Am I missing the point - are you able to add header data to a DELETE request? Thanks.
The problematic line is con.setDoOutput(true);. Removing that will fix the error.
You can add request headers to a DELETE, using addRequestProperty or setRequestProperty, but you cannot add a request body.
This is a limitation of HttpURLConnection, on old Android versions (<=4.4).
While you could alternatively use HttpClient, I don't recommend it as it's an old library with several issues that was removed from Android 6.
I would recommend using a new recent library like OkHttp:
OkHttpClient client = new OkHttpClient();
Request.Builder builder = new Request.Builder()
.url(getYourURL())
.delete(RequestBody.create(
MediaType.parse("application/json; charset=utf-8"), getYourJSONBody()));
Request request = builder.build();
try {
Response response = client.newCall(request).execute();
String string = response.body().string();
// TODO use your response
} catch (IOException e) {
e.printStackTrace();
}
getOutputStream() only works on requests that have a body, like POST. Using it on requests that don't have a body, like DELETE, will throw a ProtocolException. Instead, you should add your headers with addHeader() instead of calling getOutputStream().
I know is a bit late, but if anyone falls here searching on google like me I solved this way:
conn.setRequestProperty("X-HTTP-Method-Override", "DELETE");
conn.setRequestMethod("POST");
DELETE request is an extended form of GET request, as per the android documentation you cannot write in the body of DELETE request.
HttpUrlConnection will throw "unable to write protocol exception".
If you still want to write the parameter in the body, i suggest you to use the OKHttp Library.
OKHttp documentation
If you are intrested to use more simpler library then you can try
SimpleHttpAndroid library
One thing to remember here is if you are not writing anything in the body then remove the line
conn.setDoOutput(true);
Thanks, Hopefully it may help.
Try below method for call HttpDelete method, it works for me, hoping that work for you as well
String callHttpDelete(String url){
try {
HttpParams httpParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParams, 15000);
HttpConnectionParams.setSoTimeout(httpParams, 15000);
//HttpClient httpClient = getNewHttpClient();
HttpClient httpClient = new DefaultHttpClient();// httpParams);
HttpResponse response = null;
HttpDelete httpDelete = new HttpDelete(url);
response = httpClient.execute(httpDelete);
String sResponse;
StringBuilder s = new StringBuilder();
while ((sResponse = reader.readLine()) != null) {
s = s.append(sResponse);
}
Log.v(tag, "Yo! Response recvd ["+s.toString()+"]");
return s.toString();
} catch (Exception e){
e.printStackTrace();
}
return s.toString();
}
You can't just use the addHeader() method?
Here is my Delete request method.
Simply it is post request with extra RequestProperty
connection.setRequestProperty("X-HTTP-Method-Override", "DELETE");
Below the complete method.
public void executeDeleteRequest(String stringUrl, JSONObject jsonObject, String reqContentType, String resContentType, int timeout) throws Exception {
URL url = new URL(stringUrl);
HttpURLConnection connection = null;
String urlParameters = jsonObject.toString();
try {
connection = (HttpURLConnection) url.openConnection();
//Setting the request properties and header
connection.setRequestProperty("X-HTTP-Method-Override", "DELETE");
connection.setRequestMethod("POST");
connection.setRequestProperty("User-Agent", USER_AGENT);
connection.setRequestProperty(CONTENT_TYPE_KEY, reqContentType);
connection.setRequestProperty(ACCEPT_KEY, resContentType);
connection.setReadTimeout(timeout);
connection.setConnectTimeout(defaultTimeOut);
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
// Send request
DataOutputStream wr = new DataOutputStream(connection.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
responseCode = connection.getResponseCode();
// To handle web services which server responds with response code
// only
try {
response = convertStreamToString(connection.getInputStream());
} catch (Exception e) {
Log.e(Log.TAG_REST_CLIENT, "Cannot convert the input stream to string for the url= " + stringUrl + ", Code response=" + responseCode + "for the JsonObject: " + jsonObject.toString(), context);
}
} catch (
Exception e
)
{
if (!BController.isInternetAvailable(context)) {
IntentSender.getInstance().sendIntent(context, Constants.BC_NO_INTERNET_CONNECTION);
Log.e(Log.TAG_REST_CLIENT, "No internet connection", context);
}
Log.e(Log.TAG_REST_CLIENT, "Cannot perform the POST request successfully for the following URL: " + stringUrl + ", Code response=" + responseCode + "for the JsonObject: " + jsonObject.toString(), context);
throw e;
} finally{
if (connection != null) {
connection.disconnect();
}
}
}
I hope it helped.
To add closure to this question, it transpired that there is no supported method to send an HTTP DELETE request containing header data.
The solution was for the client to alter their API to accept a standard GET request which indicated that the action should be a delete, containing the id of the item to be deleted.
http://clienturl.net/api/delete/id12345

Categories

Resources