missing parameter when sending request to server with HttpURLConnection - android

I need to post schoolname=xyz&schoolid=1234 to server. I wrote the following Android client code:
String data = "schoolname=xyz&schoolid=1234";
//The url is correct
HttpURLConnection conn = (HttpURLConnection)url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setRequestProperty("Accept-Encoding", "gzip");
conn.setDoInput(true);
conn.setDoOutput(true);
OutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(data.toString().getBytes("UTF-8"));
//response complains that missing parameter 'schoolname'
int responseCode = conn.getResponseCode();
...
After I send my request with above code, server however constantly complains that schoolname parameter is missing. What do I miss or did wrong?

Have a look at [this example that explains How to use a HttpURLConnection to POST data
If you're planning on doing a lot of web communication, take a look at Square's Retrofit which will help you automate a lot of this work.

You can't use the format "key=value&key1=value1" for http post. That would work fine only for get. In this case you need something like this:
List<NameValuePair> nameValuePairs;
nameValuePairs.add(new BasicNameValuePair("schoolname", "xyz"));
nameValuePairs.add(new BasicNameValuePair("schoolid", "1234"));
HttpPost httpPost = new HttpPost(url);
httpPost.setEntity(new UrlEncodedFormEntity(nameValuePairs, "UTF-8"));
httpPost.execute();

I figured out myself, the reason is that I forget to call flush() on output stream. After flush it, everything works fine.

Related

Why can't I set header with Android HTTPURLConnection?

So I'm trying to connect to a REST server with HTTPURLConnection. The HTTPGET request needs to be of content-type application/json. When I use setRequestProperty("Content-Type", "application/json"); the value is overriden to "text/html" but when I use setRequestProperty("Accept", "application/json"); the Content-Type is set to application/json. Why can't I use Content-Type when specifying? Clarification is greatly appreciated.
My current guess is that "Accept" works with HTTPGET and "Content-Type" is for HTTPPOST.
More code:
connection.setRequestMethod("GET");
connection.setUseCaches(false);
//connection.setRequestProperty("Content-Type", "application/json");
connection.setRequestProperty("Accept", "application/json");
AFAIK, the Content-Type header in an HTTP request would be for the type of content being sent as the body, and is used on requests like POST and PUT. Accept is the header that indicates what MIME types the requester would like to receive in a response.

setRequestProperty throwing java.lang.IllegalStateException: Cannot set request property after connection is made

I am getting java.lang.IllegalStateException:
java.lang.IllegalStateException: Cannot set request property after connection is made error when setRequestProperty method is called after
url.openConnection();
Here is what i am trying:
URL url = new URL("https://49.205.102.182:7070/obsplatform/api/v1/mediadevices/545b801ce37e69cc");
urlConnection = (HttpsURLConnection) url
.openConnection();
urlConnection.setRequestProperty("Content-Type","application/json");
any suggestions please? Thanks in advance.
This usually happens if you have in the debug watchers calls, such as conn.getResponseCode() or anything that queries the request result before the request was actually issued or completed.
This causes, that during debug, a request is performed by the watcher, before having properly set you request, and then it becomes invalid.
I only have this issue while in debugging mode,
Run without debugging (You can print logs) everything should work fine
The obvious thing is to think that you need to add properties before calling open on the URL. this however is not the case. i have seen many samples of settings being set AFTER url has been open (as counter intuitive as that is).
the problem in my case is that i had conn.getResponseCode() added in my watch list. removed that and all good.
... tricky.
please check below code
HttpURLConnection httpcon = (HttpURLConnection) ((new URL("a url").openConnection()));
httpcon.setDoOutput(true);
httpcon.setRequestProperty("Content-Type", "application/json");
httpcon.setRequestProperty("Accept", "application/json");
httpcon.setRequestMethod("POST");
httpcon.connect();
I was getting the same exception on setRequestProperty("Range","byte=" + downloadedSize + "-") .
After adding connection.setChunkedStreamingMode(0); the issue disappeared
I'm having the same issue.
I was observing this issue on Nexus 5. Code of my app constantly fails with the same exception (or its twin brother "cannot set request method ..")
What I've observed that it happens if i leave phone for a while. One it starts failing it fails all the time - but if i restart phone/emulator it's ok once again).
My suspicion is its either some bug in connection pooling on framework side, or somewhere in code resources are leaked.
i found the problem it's about ordering the code, if you are trying to add header and post parameters both, it's important to be careful about this
HttpURLConnection connection = (HttpURLConnection) urlConnection;
//// Add Request Headers
for (NameValuePair nvp :
request[0].getHeaderParams()) {
connection.setRequestProperty(nvp.getName(),nvp.getValue());
}
// done
connection.setDoInput(true);
connection.setDoOutput(true);
connection.setRequestMethod("POST");
//// Add Post Parameters
OutputStream outputStream = urlConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream));
List<NameValuePair> params = new ArrayList<>(request[0].getPostParams());
bufferedWriter.write(getQuery(params));
// done
connection.setConnectTimeout(3000);
connection.setReadTimeout(3000);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.flush();
outputStream.close();
connection.connect();
in here, i have added header parameters then set setDoInput and setDoOutput then setRequestMethod and finally you can add POST parameters.
i don't know what is wrong with setRequestMethod but i think its preparing the connection by opening it or something and that's why it throws exception
not invoke setRequestProperty after write byte to OutputStream.
OutputStream os = connection.getOutputStream();
os.write("k=v".getBytes());
os.close();
you should invoke setRequestProperty above the code
To avoid the error:
java.lang.IllegalStateException: Cannot set request property after connection is made
We have to check the connection response before access the request header fields :
URL url = new URL("https://49.205.102.182:7070/obsplatform/api/v1/mediadevices/545b801ce37e69cc");
urlConnection = (HttpsURLConnection) url
.openConnection();
//Check connection
if(urlConnection.getResponseCode() == 200/*Successful*/) {
urlConnection.setRequestProperty("Content-Type","application/json");
...
...
}

Android HttpPut Has No Body, Despite Setting the Entity

I'm trying to PUT some XML to a server, but the gist of it is that no matter what I do, HttpPut simply won't put anything in the Http body. The server always comes back saying that the body is missing, and looking at it through Wireshark, nothing is there! Here's the code I'm using to set up and run the request:
HttpPut putRequest = new HttpPut(urlString]);
StringEntity stringEntity = new StringEntity(xmlString, HTTP.ISO_8859_1);
stringEntity.setContentType("text/xml");
putRequest.setEntity(stringEntity);
putRequest.addHeader("Host", formatUrlForHostHeader(broadsoftUrl));
putRequest.addHeader("Authorization", authorizationString);
putRequest.addHeader("Content-Type", "text/xml");
putRequest.addHeader("Accept", "text/xml");
response = httpClient.execute(putRequest);
I'm not sure what else to include here. I tried it on 4.2 and 4.0.3. This code is running in the doInBackground of an AsyncTask. The response code I get is a 409 Conflict, and the body is the server's application-specific message, telling me the body is missing. I confirmed that it's missing with Wireshark.
EDIT:
An interesting note is that I ran the same code standalone on my desktop, and it worked. So, is there something up with the Android versions of HttpClient, or the system? I tried a few different API levels, too, just to check.
Any thoughts?
Thanks!
Alright, so the solution was to just give up on HttpPut and all that, and use HttpURLConnection. Here's how we ended up doing it:
URL url = new URL(theUrl);
HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
httpCon.setRequestProperty("Host", formatUrlForHostHeader(broadsoftUrl));
httpCon.setRequestProperty("Authorization", authorizationString);
httpCon.setRequestProperty("Content-Type", "text/xml; charset=ISO_8859_1");
httpCon.setRequestProperty("Accept", "text/xml");
httpCon.setDoInput(true);
httpCon.setDoOutput(true);
httpCon.setRequestMethod("PUT");
OutputStreamWriter out = new OutputStreamWriter(httpCon.getOutputStream(), "ISO_8859_1");
out.write(xmlData);
out.close();
if(httpCon.getErrorStream() == null) {
return "";
} else {
return "ERROR";
}
We didn't need to get the response from our PUT request, but you check if it failed by seeing if the error stream exists. If you wanted to get the response, you would do something like this:
StringWriter writer = new StringWriter();
IOUtils.copy(httpCon.getInputStream(), writer, encoding);
String responseString = writer.toString();
Of course, you would have to include Apache's IOTools in your app.
409 Conflict is usually an Edit Conflict error, usually associated with wikis, but it could be any type of conflict with the request.
http://en.wikipedia.org/wiki/List_of_HTTP_status_codes
http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
What type of data are you trying to post and is it possible that the host has existing data that cannot be changed?

Android HTC Sense - Http Request/ Response exception

Working on the emulator, but when I am trying on an HTC Sense, i have got an exception on the last line of this code
url = new URL(urlString);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/json; charset=utf-8");
//Send request
Gson requestGson = new Gson();
OutputStream wr = connection.getOutputStream();
The exception is java.net.ProtocolException: Does not support output for the connection.getOutputStream();
I am testing on API 10, Gingerbread on an HTC Sense (remote debugging).
anyone has encountered this problem before?
Thanks.
David.
Try calling setDoOutput(true). It is needed for POST requests. The first part of your code would change to look like this:
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/json; charset=utf-8");
connection.setDoOutput(true);
Source: https://groups.google.com/forum/?fromgroups=#!topic/android-developers/2aEYpsZEMvs
See also this other StackOverflow answer: What exactly does URLConnection.setDoOutput() affect?

Problems on POST REQUEST HttpURLConnection Android 4.0+

I'm having some trouble making a simple HTTP POST request on a website. It seems like the POST parameters is not being sent!
Scenario:
HTTP Response code 200 - Wrong User/Pass - Occurring on Android 4.0+
HTTP Response code 302 - User/Pass OK - Occurring on others SDK versions
The Web form thats works OK:
<form id="form_mn_login" enctype="application/x-www-form-urlencoded" action="http://dummyhost/r.php" class="estil" accept-charset="utf-8" method="post">
<input type="text" name="m_email" id="m_email" />
<input type="password" name="m_senha" id="m_senha" />
The code (inside doInBackground AsyncTask's method):
urlParameters = "m_email="
+ URLEncoder.encode(username, "UTF-8") + "&m_senha="
+ URLEncoder.encode(password, "UTF-8");
URL url;
HttpURLConnection connection = null;
// Create connection
url = new URL("http://dummyhost/r.php");
connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.setRequestProperty("Content-Type",
"application/x-www-form-urlencoded");
connection.setRequestProperty("Content-Language", "en-US");
connection.setUseCaches(false);
connection.setDoInput(true);
connection.setDoOutput(true);
// Send request
DataOutputStream wr = new DataOutputStream(
connection.getOutputStream());
wr.writeBytes(urlParameters);
wr.flush();
wr.close();
publishProgress(30);
Log.w("responsecode", Integer.toString(connection.getResponseCode()));
This issue only shows up when I emulate it on Android 4.0+ AVD Devices. (Tried on 2.2,2.3.3, 3.0 and it works flawlessly)
What am I missing?
I'm aware maybe this is an server issue, but I really believe there must be an workaround for this. I've tried thousands of different ways of doing it but none seems to work as it should.
Thanks a lot,
RC

Categories

Resources