First Web API call delay, from Android application - android

I have a Web API Asp .Net that can receive an HTTP Post request. I have tested the web service from Postman - Rest Client, or other similar application, and all works fine: the web service responses me immediately. But If I try to call the same web service from my Android application I have a problem:
The first call to web service is slow, while the nexts are fast. If I stop to call the ws, and then I retry, for example after 1 minute, the ws response is slow again, and the next ones are fast...an so on.
Here, the code I use for call web service.
String wsURI = "www.myWsUrl...";
url = new URL(wsURI);
try{
httpConnection = (HttpURLConnection) url.openConnection();
httpConnection.setDoInput(true); // ?
httpConnection.setDoOutput(true);
httpConnection.setRequestMethod("POST");
httpConnection.setRequestProperty("Content-Type", "application/json");
JSONStringer requestData = new JSONStringer()
.object()
.key("id").value(12)
.key("frequence").value(1000)
.key("code").value("ABCAB-0123")
.endObject();
BufferedWriter out = new BufferedWriter(new OutputStreamWriter(httpConnection.getOutputStream()));
out.write(requestData.toString());
out.close();
resCode = httpConnection.getResponseCode();
...
}catch(){
...
}finally{
if(httpConnection!=null)
httpConnection.disconnect();
}

Related

JsonWriter POST not working in Android to WCF web service

I would like to know anyone has a sample code on how to use JsonWriter to post JSON data to WCF web service from Android?
I tested my WCF with Fiddler 4 (Composer with POST json data) and it gave me the correct return.
However, when I tested with my Android application which use JsonWriter, I didn't see any action on Fiddler (I set up Fiddler to check on my Android Emulator network traffic, by the way, I am testing on Android Emulator.).
With the same Android application, I can call GET with JsonReader to my WCF and get the correct reply.
Its just calling POST with JsonWriter got no response code or no action in Fiddler.
For JsonWriter (and Reader), I refer to Android developer >> JsonWriter
Here are my test results (Get and Post) with Emulator GET and POST.
Here are my test results with Fiddler direct POST.
First it gave me Result 307 then follow by 200.
And here is how I use JsonWriter to post (this block was from AsyncTask).
try
{
Log.d("TEST_JSON", "URL: " + params[0]);
URL url = new URL(params[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Accept","application/json");
conn.setRequestProperty("Content-Type","application/json");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setUseCaches(false);
conn.setAllowUserInteraction(false);
// conn.connect();
OutputStream out = conn.getOutputStream();
JsonWriter writer = new JsonWriter(new OutputStreamWriter(out, "UTF-8"));
try
{
writer.setIndent(" ");
if(params[1].trim() == "ARRAY")
{
// Write array to WCF.
}
else if(params[1].trim() == "OBJ")
{
// Write object to WCF. <<== I am testing with one object.
writer.beginObject();
writer.name("ShipNo").value("SI10101");
writer.name("DoNo").value("DO230401");
writer.name("PartNo").value("102931-1201");
writer.name("Qty").value(1);
writer.name("ShipIn").value(1);
writer.endObject();
}
}
finally
{
writer.close();
out.close();
}
// If I enable below blocks, I will see 307 response code in Fiddler.
/*
conn.connect();
int responseCode = conn.getResponseCode();
Log.d("TEST_JSON", "Code: " + String.valueOf(responseCode));
*/
Log.d("TEST_JSON", "Finish sending JSON.");
conn.disconnect();
}
catch (IOException e)
{
Log.e("TEST_JSON",e.getMessage()); // <<-- No error from this try catch block.
}
I tried and still cannot figure out why JsonWriter didn't trigger to my WCF (I attached my WCF to my localhost service, only Fiddler direct POST will hit the break point in my WCF project while Android App didn't reach to it). I follow the exact example from Android Developer site though. I google and didn't find any site on using JsonWriter with OutputStreamWriter (I saw some post using StringWriter).
May I know where did my code wrong ?
Based on this StackOverFlow post WCF has a 'Thing' about URI, I managed to solve this issue.
All I need is to make sure my POST web service has URI Template ends with "Slash".
Example: http://10.72.137.98/myWebSvc/posvctFun/
Instead of http://10.72.137.98/myWebSvc/postFun

getResponseCode weather times out nor reads response

I have an android application which can upload some json data to a PHP script which stores the data in a database.
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
try {
connection.setDoOutput(true);
connection.setInstanceFollowRedirects(false);
connection.setRequestMethod("PUT");
connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("charset", "utf-8");
connection.setFixedLengthStreamingMode(bytes.length);
connection.setReadTimeout(3000000);
long tim = System.currentTimeMillis();
connection.getOutputStream().write(bytes);
connection.getOutputStream().flush();
if (connection.getResponseCode() != 200) {
long dur = System.currentTimeMillis() - tim;
String response = IOUtils.toString(connection.getInputStream(), "UTF-8");
throw new IOException(connection.getResponseCode() + " " + response);
}
} finally {
connection.disconnect();
}
The data arrives at the script and the scripts stores the data into the database.
When the client uploads a huge amount of data the request takes about 15 minutes, though it completes. The data is completly written into the database and the php script sends it's response.
But when it takes that long the getResponseCode() function never returns. When i hit pause in the debugger it shows me the following stack:
Any idea what's running wrong?
I'm running an emulator on API level 23.
It seems that the connection gets lost but android does not detect it.

request to MVC4 WEB API with Get method from android return 405

I have ASP.Net MVC4 WEB API, hosted in local IIS.
I request the api from android using GET method. Response is 405 Action not Allowed.
I Have This Method in Controller :
public IEnumerable<Table> GET()
{
return _repository.GetAll();
}
But When I Change the Method to POST:
public IEnumerable<Table> POST()
{
return _repository.GetAll();
}
and request from android with POST method.
I got the RESULTS.
I request both GET and POST with the same route.
'/api/tables'
In android project, I use HttpUrlConnection to request API.
try{
URL url = new URL(urls[0]);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(5000 /* milliseconds */);
conn.setConnectTimeout(7500 /* milliseconds */);
conn.setRequestProperty("Accept", "application/json");
conn.setRequestMethod(method);
conn.setDoInput(true);
if(method == "POST")
conn.setDoOutput(true);
if(params != null){
// Get OutputStream for the connection and
// write the parameter query string to it
OutputStream os = conn.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os, "UTF-8"));
writer.write(getURLEncodedString(params));
writer.flush();
writer.close();
}
// Starts the query
conn.connect();
What am i doing wrong?
info:
when request from browser Get Method return results and Post Method 405.
The problem is in my android project
Android Developer: HttpUrlConnection
HttpURLConnection uses the GET method by default. It will use POST if
setDoOutput(true) has been called.
stackoverflow: https://stackoverflow.com/questions/8187188/android-4-0-ics-turning-httpurlconnection-get-requests-into-post-requests
May be it's a routing issue. Make some little changes in your WebApi.config of webapi
config.Routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
One more important thing here is that with this style of routing, you must use attributes to specify the allowed HTTP methods (like [HttpGet]).

Why connection is not establishing on first time?

I want to send my id & password to server and get the response from server. Here is my code. It is not working for the first time. But iam getting the response from server if i execute my application on second time. It is throwing "Post method failed: -1 null" on first time. Where iam wrong?? Why if() block is executing on first time?? could you please tell me.
HttpsURLConnection con = null;
String httpsURL = "https://www.abc.com/login";
String query = "id=xyz&password=pqr";
URL url = new URL(httpsURL);
con = (HttpsURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-length", String.valueOf(query.length()));
con.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
con.setRequestProperty("User-Agent","Mozilla/4.0(compatible; MSIE 5.0; Windows 98; DigExt)");
con.setDoInput(true);
con.setDoOutput(true);
DataOutputStream output = new DataOutputStream(con.getOutputStream());
output.writeBytes(query);
output.close();
int respCode = con.getResponseCode();
if (respCode != HttpsURLConnection.HTTP_OK)
{
throw new Exception("POST method failed: " + con.getResponseCode()+ "\t" + con.getResponseMessage()); }
else {
//read the content from server
}
1/ It is recommanded to use apache HttpClient rather than URLConnection (see http://developer.android.com/reference/org/apache/http/impl/client/DefaultHttpClient.html)
2/ for login and password, why not use Http Authentication ? both basic and digest are supported by android.
3/ as for you problem, you don't close the underlying outputStream.
you should do:
OutputStream os = con.getOutputStream();
DataOutputStream output = new DataOutputStream(os);
output.writeBytes(query);
output.close();
os.close();
Check Server service validity with other technology and/or classic java. You didn say in your question if you succeed to discriminate the server from the issue.
from java doc ...getResponseCode returns -1 if no code can be discerned from the response (i.e., the response is not valid HTTP).
Java https post request example : http://www.java-samples.com/java/POST-toHTTPS-url-free-java-sample-program.htm
try to close your outputstream after querying the status and not before...that may help
Here is how you should send POST requests in Android
HttpPost httpGet = new HttpPost(server + "/login?email="+username+"&password="+password);
DefaultHttpClient httpClient = new DefaultHttpClient();
HttpResponse response = httpClient.execute(httpGet);
You can read response using:
response.getEntity().getContent()

Does Android Support a server made on ashx or ASP.NET Web Handler file

I have an android application that have to communicate with the server using post method in HTTP. My application work fine whenever i open some other sites having basic page may be html or others but whenever i want to open my server file it gives nothing even though with get method in HTTP.
The blank response from the server can be understandable that what i am getting because i have to send some headers with post method as a request and ashx will send some response to it.
But still as expected by get method in HTTP the basic information of the page have to be retrieved.
for eg. my server url is http://172.17.3.90/RMALite/RLHandler.ashx
and the basic response from the get method have to be like this.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=windows-1252"></HEAD>
<BODY></BODY></HTML>
Unfortunately i am getting nothing
but whenever i changed the url to open other sites it work fine and i got the response in text html format.
So my Question is, Android require some stuff to handle ASP.NET handler or ashx file as compare to other sites or URL's?
I know it late now but other can get benefit. Below is code snippet which help me to get accomplished same issue.
public static String excutePost(String targetURL, String urlParameters) {
//targetURL =http://172.17.3.90/RMALite/RLHandler.ashx
URL url;
HttpURLConnection connection = null;
try {
// Create connection
url = new URL(targetURL);
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Length", ""
+ Integer.toString(urlParameters.getBytes().length));
connection.setRequestProperty("Content-Language", "en-US");
connection.setRequestProperty("method-name", "parameter-value");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
// // Send request
DataOutputStream wr = new DataOutputStream(connection
.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
String field1 = connection.getHeaderField("field1");
String field2 = connection.getHeaderField("field2");
return anyArray;
} catch (Exception e) {
e.printStackTrace();
return null;
} finally {
if (connection != null) {
connection.disconnect();
}
}
}
I believe it would be helpful n much appreciated to this post
thanks much
-y

Categories

Resources