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.
Related
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();
}
I've got an app targeting ICS and above, and I'm trying to use HttpsURLConnection and HttpResponseCache to cache a web service response. It makes the request with an etag, and the server will return 304 if not modified. It appears to be returning stuff from the cache, however, I'm not receiving any indication that the response is from cache. The response code I'm getting from connection.getResponseCode() is 200, not 304. I need to know if it's cached because I want to know if it's changed so I can mark it as read (it's a fairly long string, and I would not like to have to compare the two). Is there something I can set or something I can check so I know that it is from the cache instead of freshly fetched?
You can try using the response header information. Compare the dates, if you are getting the same date for the same request, then it's the cache.
HttpURLConnection conn;
conn = (HttpURLConnection)url.openConnection();
...
conn.connect();
System.out.println(conn.getHeaderField("Date"));
if you want to print the whole header:
Map headerfields = conn.getHeaderFields();
Set headers = headerfields.entrySet();
for(Iterator i = headers.iterator(); i.hasNext();){
Map.Entry map = (Map.Entry)i.next();
System.out.println(map.getKey() + " : " + map.getValue() + "");
}
After print the whole response header on Android 9. I found the following fields useful.
HttpURLConnection conn;
...
conn.getHeaderField("X-Android-Response-Source"); // "NETWORK 200" or "CACHE 200"
conn.getHeaderField("Warning"); // null or "110 HttpURLConnection "Response is stale""
It should have other status messages that I have not tested.
My Android tablet application does not work with ICS due to a Login problem. When I looked at my code and ran it under debug mode on an ICS tablet, I see the problem but I don't understand it. The code functions correctly on all Honeycomb models that i have tested and in fact I have two tablets hooked up to my computer (one Samsung Galaxy Tab running 3.2, and a Motorola Xoom wifi running 4.0.3) and the code fails on ICS and works on HC.
The failure is a Socket Timeout exception. The timeout was 2000ms, but I upped it to 100000ms to test and it had no impact.
Using the browser on the ICS tablet, I can go to the URL and it responds, so it doesn't appear to be network related.
I am running on a background thread using AsyncTask.
Slurp just takes all of the input from the InputStream and using StringBuilder creates a string representation. Its not actually useful in this request but I added it to see what the server was replying with.
I am POSTing to the page the same way a user authenticates using the form, which is why I am using x-www-form-urlencoded.
Again, this code functions perfectly on Honeycomb but fails on ICS.
The code makes a connection but fails when it asks for a response from the server, almost like the server is still waiting for something... anyway, here is the code:
static public String authenticate(String service_url, String username, String password) throws IOException {
if (username == null || password == null)
throw new IOException();
String charset = "UTF-8";
String query = String.format("Email=%s&Password=%s",URLEncoder.encode(username, charset),URLEncoder.encode(password, charset));
byte [] data = query.getBytes(charset);
URL url = new URL(service_url);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setRequestProperty("Accept-Charset", charset);
connection.setRequestProperty("Content-Length", Integer.toString(data.length));
connection.setDoOutput(true);
connection.setRequestMethod("POST");
connection.setReadTimeout(5000); // 2 second timeout.
try {
connection.connect();
DataOutputStream pw = new DataOutputStream (connection.getOutputStream());
pw.writeBytes(query);
pw.flush();
pw.close();
int code = connection.getResponseCode(); //SOCKET TIMEOUT HERE
if (code == 200 || code == 302)
{
InputStream is = connection.getInputStream();
String value = slurp(is);
List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
if (cookies == null)
throw new IOException();
for (String cookie : cookies) {
if (cookie.startsWith("cpms")) {
cookieTime = new DateTime(); //crazy but the expires time in the cookie is not actually accurate.
return cookie; // this is the only correct path out.
}
}
}
else
Logger.e(StaticUtils.class, "Invalid response code while logging in: " + code);
}
catch (IOException ioe)
{
Logger.e(StaticUtils.class, ioe);
throw ioe; // log it and then throw it back.
} finally {
connection.disconnect();
}
return null;
}
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()
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