calling RESTful WCFservice method with object as parameter from java - android

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

Related

Android calling webservice issue

i am calling webservice in this way..
public static String POST(String url, ArrayList<ModelLatLog> list,Context con){
InputStream inputStream = null;
String result = "";
AppLog.logString(TAG+"URL : "+url);
AppLog.logString(TAG+"ListSize: "+list.size());
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
String json = "[";
for(int j=0;j<list.size();j++){
JSONObject jsonObject = new JSONObject();
jsonObject.accumulate("DId", ""+list.get(j).get_idDevice());
jsonObject.accumulate("Lat", ""+list.get(j).getLat());
jsonObject.accumulate("Long", ""+list.get(j).getLong());
jsonObject.accumulate("DIn", ""+list.get(j).getDt());
jsonObject.accumulate("TIn", ""+list.get(j).getTm());
jsonObject.accumulate("Dce", ""+list.get(j).getDce());
if(j==0 ){
json = json+""+jsonObject.toString();
AppLog.logString(TAG+"if j: "+j);
}
else{
json = json+","+jsonObject.toString();
AppLog.logString(TAG+"else j: "+j);
}
}
json = json+"]";
AppLog.logString(TAG+"JSON: "+json);
StringEntity se = new StringEntity(json);
httpPost.setEntity(se);
httpPost.setHeader("Accept", "application/json");
httpPost.setHeader("Content-type", "application/json");
HttpResponse httpResponse = httpclient.execute(httpPost);
int resopnceStatus = httpResponse.getStatusLine().getStatusCode();
AppLog.logString(TAG+"set data resopnceStatus: "+resopnceStatus);
inputStream = httpResponse.getEntity().getContent();
if(inputStream != null)
result = convertInputStreamToString(inputStream);
else
result = "Did not work!";
} catch (Exception e) {
e.printStackTrace();
AppLog.logString("InputStream"+ e.getLocalizedMessage());
}
return result;
}
AppLog is nothing it's log.d
it's giving me error like
11-19 18:15:39.088: I/Service(32261): Utility: set data resopnceStatus: 500
11-19 18:15:39.096: I/Service(32261): result: <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><soap:Code><soap:Value>soap:Receiver</soap:Value></soap:Code><soap:Reason><soap:Text xml:lang="en">Server was unable to process request. ---> Data at the root level is invalid. Line 1, position 1.</soap:Text></soap:Reason><soap:Detail /></soap:Fault></soap:Body></soap:Envelope>
Looks like the webservice is returning you an error, so the HTTP POST call actually worked.
Are you sending it the correct format? looks like its expecting XML request and you send JSON.
Why you are Taking so burden...
Just use volley service...It will take care of every thing...
Just use StringRequest in Volley..your task will be easy...
Download volley example here
If you haven't already figure out your problem, I believe ksoap2 is more intuitive for dealing with webservices on android, this link has a good example on it.
is there clear Example of Android ksoap2 returning array of objects from .Net Web service?

Android: Getting HTTP response incrementally like in iOS

I'm relatively new to Android (I'm an iOS-Developer) and I want to call a Webservice like I'm used to in iOS with NSURLConnectionDelegate's method
didReceiveData:(NSData *)data
I need to get the data incrementally because I'm building a streaming API that gets a lot of JSON data in response and needs to check the data for complete blocks.
Would be great if someone could help me, I've been searching for a while and didn't find a satisfying solution so far.
If you try to call web services in Android you should use the AsyncTask where the request would be made asynchronously. Have a look at the documentation. Every time you're request would be finished the method onPostExecute(Object result) would be called. Thats the method where you can go on with further processes.
The URLConnection documentation contain following example:
URL url = new URL("ftp://mirror.csclub.uwaterloo.ca/index.html");
URLConnection urlConnection = url.openConnection();
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
try {
readStream(in);
finally {
in.close();
}
If i right understood your question, just implement readStream function as you need.
I found out how to do this with the help of a friend and some links.
You need to implement an own ResponseHandler like this:
class ChunkedResponseHandler implements ResponseHandler<String> {
#Override
public String handleResponse(HttpResponse response) throws ClientProtocolException, IOException {
HttpEntity entity = response.getEntity();
InputStream stream = entity.getContent();
StringBuffer output = new StringBuffer();
byte[] b = new byte[4096];
int n;
while ((n = stream.read(b)) != -1) {
output.append(new String(b, 0, n));
// do something while input is streaming
}
return output.toString();
}
}
Now you simply have to assign the response handler when starting the request:
HttpClient client = new DefaultHttpClient();
HttpGet getRequest = new HttpGet("someURL");
ResponseHandler<String> responseHandler = new ChunkedResponseHandler();
String responseBody = client.execute(postRequest, responseHandler);

Alternative for UrlEncodedFormEntity for sending data via POST

When sending the POST request using UrlEncodedFormEntity which takes List as input parameter along with the key, my request gets converted in the form of [key={json}] .
But the request i want to send should be in the form of key={json} , i.e not as List.
So, is there any alternative for the given method when using POST?
notes: webservice is working fine , and since it is json ,i cannot use Soap .
i ve tested it using POSTman and webservices are WCF(if thats of any use..)
if any code is required , please mention it.
Thanks in advance.
Edit code:
HttpClient client = new DefaultHttpClient();
HttpPost request = new HttpPost(URL);
List<NameValuePair> value=new ArrayList<NameValuePair>();
value.add(new BasicNameValuePair("data",string));
//here it passes as List and here is where i want an alternate method
// by which i can send parameter as JSONobject
UrlEncodedFormEntity entity=new UrlEncodedFormEntity(value);
request.setEntity(entity);
HttpResponse response = client.execute(request);
HttpEntity entity2 = response.getEntity();
if(entity2.getContentLength() != 0) {
Reader tapReader = new InputStreamReader(response.getEntity().getContent());
char[] buffer = new char[(int) response.getEntity().getContentLength()];
tapReader.read(buffer);
tapReader.close();
JSONObject tapJsonObj = new JSONObject(buffer);

How to send a JSON object over HttpClient Request with Android?

I want to send the JSON text {} to a web service and read the response. How can I do this from android? What are the steps such as creating request object, setting content headers, etc.
My code is here
public void postData(String result,JSONObject obj) {
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpParams myParams = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(myParams, 10000);
HttpConnectionParams.setSoTimeout(myParams, 10000);
String json=obj.toString();
try {
HttpPost httppost = new HttpPost(result.toString());
StringEntity se = new StringEntity(obj.toString());
se.setContentEncoding(new BasicHeader(HTTP.CONTENT_TYPE, "application/json"));
httppost.setEntity(se);
HttpResponse response = httpclient.execute(httppost);
String temp = EntityUtils.toString(response.getEntity());
Log.i("tag", temp);
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
}
what mistake i have done plz correct me because it shows me an bad request error
but when i do post in poster it shows me status as Successfull 200 ok
I do this with
httppost.setHeader("Content-type", "application/json");
Also, the new HttpPost() takes the web service URL as argument.
In the try catch loop, I did this:
HttpPost post = new HttpPost(
"https://www.placeyoururlhere.com");
post.setHeader(HTTP.CONTENT_TYPE,"application/json" );
List<NameValuePair> nameValuePairs = new
ArrayList<NameValuePair>(1);
nameValuePairs.add(new BasicNameValuePair("json", json));
post.setEntity(new UrlEncodedFormEntity(nameValuePairs));
HttpClient client = new DefaultHttpClient();
HttpResponse resp = client.execute(post);
HttpEntity entity = resp.getEntity();
response = EntityUtils.toString(entity);
You can add your nameValurPairs according to how many fields you have.
Typically the JSON might become really huge, which I will then suggest gzipping it then sending, but if your JSON is fairly small and always the same size the above should work for you.
If it is a web service and not RestAPI call then, you can get the WSDL file from the server and use a SOAP Stub generator to do all the work of creating the Request objects and the networking code for you, for example WSClient++
If you wish to do it by yourself then things get a little tricky. Android doesn't come with SOAP library.
However, you can download 3rd party library here: http://code.google.com/p/ksoap2-android/
If you need help using it, you might find this thread helpful: How to call a .NET Webservice from Android using KSOAP2?
If its a REST-API Call like POST or GET to be more specific then its is very simple
Just pass a JSON Formatted String object in you function and use org.json package to parse the response string for you.
Hope this helps.

How to set header using http post method

i am currently working on one application..
in that application i have to use get and post both methods..
get method works properly but in post method suddenly i get the response like
"invalid method.post required"..
my code for that is:
String list_url = "************************";
try {
String appand = TimeStampForAuth.TimeStameMethod(main.this);
String auth = android.util.Base64.encodeToString(("iphone" + ":" +
"2a5a262d5a")
.getBytes("UTF-8"), android.util.Base64.NO_WRAP);
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost(list_url+appand);
Log.d("URL_LIST", list_url+appand);
List nvps = new ArrayList();
nvps.add(new BasicNameValuePair("login",Login));
nvps.add(new BasicNameValuePair("password",password));
nvps.add(new BasicNameValuePair("title",title));
nvps.add(new BasicNameValuePair("category_id",cat_id));
UrlEncodedFormEntity p_entity = new UrlEncodedFormEntity(nvps,HTTP.UTF_8);
post.addHeader("Authorization", "Basic " + auth);
post.setEntity(p_entity);
HttpResponse response = client.execute(post);
HttpEntity responseEntity = response.getEntity();
String s = EntityUtils.toString(responseEntity);
Log.d("List response", s);
}
catch(Exception e){
System.out.println(e.toString());
}
in that i am missing somethinf or what that i dont know..is all that thing is valid for post method....
please help me as early as possible...
thanking you.........
Try using setHeader() instead of addHeader()
You could try HttpClient 4.1 for Android: http://code.google.com/p/httpclientandroidlib/
(There are bugs in the HttpClient version 4.0 which Android uses.)
You can also debug with it a little more with httpClient.log.enableDebug(true);
If you don't want to use an external library, I'd start debugging the network traffic.
With a software called Wireshark you can see and inspect all Http Requests/Responses very
easily.
For authorization I personally would use:
httpClient.getCredentialsProvider().setCredentials(
new AuthScope(hostname, port),
new UsernamePasswordCredentials(user, pass));
use this instead:
HttpURLConnection connection = (HttpsURLConnection) serviceURL.openConnection();
connection.setRequestMethod("POST");

Categories

Resources