I am making an Http POST request to a Url https://nitos.gr in android.
The url has not domain name. Stackoverflow does not allow me to include URL with numbers in my text, so i just write a random url https://nitos.gr for having an example.
I get a 400 response code, and print the getErrorStream() giving libcore.net.http.UnknownLengthHttpInputStream@41eba330
However, i perform succesfully HTTP GET request. The url is https, thus i have a fake trust manager allowing all SSL connections.
In summary:
Protocol: HTTPS
GET Request: successful
POST Request: Fails
Request code: 400
Error message: java.io.FileNotFoundException: https://nitos.gr
ErrorStream: java.io.FileNotFoundException: https://nitos.gr
The method performing the POST Request follows:
public void setTestbedData(String path, String data) {
HttpURLConnection con = null;
try {
con = (HttpURLConnection) ( new URL(Constants.BASE_URL + path)).openConnection();
// If you invoke the method setDoOutput(true) on the URLConnection, it will always use the POST method.
con.setRequestMethod("POST");
con.setDoInput(true);
con.setDoOutput(true);
con.setRequestProperty("Accept", "application/json");
con.setRequestProperty("Content-Type", "application/json");
Log.i("data", data);
OutputStream outputStream = con.getOutputStream();
outputStream.write(data.getBytes());
outputStream.flush();
Log.w("RESPONSE CODE", "code " + con.getResponseCode());
Log.w("this is connection ",""+con);
InputStream errorstream = con.getErrorStream();
Log.w("GetErrorStream ", ""+errorstream);
InputStream _is;
if (con.getResponseCode() >= 400) {
_is = con.getInputStream();
} else {
_is = con.getErrorStream();
String result = getStringFromInputStream(_is);
Log.i("Error != 400", result);
}
if (con.getResponseCode() != 200) {
throw new RuntimeException("Failed : HTTP error code : "
+ con.getResponseCode());
}
BufferedReader responseBuffer = new BufferedReader(new InputStreamReader((con.getInputStream())));
String output;
Log.i("TestbedHttpClient","Output from Server:");
while ((output = responseBuffer.readLine()) != null) {
Log.i("Output",output);
}
con.disconnect();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
RESPONSE CODE(18936): code 400 libcore.net.http.HttpsURLConnectionImpl$HttpUrlConnectionDelegate:https://nitos.gr GetErrorStream(18936): libcore.net.http.UnknownLengthHttpInputStream@41eba330 System.err(18936): java.io.FileNotFoundException: https://nitos.gr System.err(18936): at libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)
Replace following code
Log.w("this is connection ",""+con);
InputStream errorstream = con.getErrorStream();
Log.w("GetErrorStream ", ""+errorstream);
InputStream _is;
if (con.getResponseCode() >= 400) {
_is = con.getInputStream();
} else {
_is = con.getErrorStream();
String result = getStringFromInputStream(_is);
Log.i("Error != 400", result);
}
with
InputStream _is;
if (con.getResponseCode() / 100 == 2) { // 2xx code means success
_is = con.getInputStream();
} else {
_is = con.getErrorStream();
String result = getStringFromInputStream(_is);
Log.i("Error != 2xx", result);
}
Or in other words: It doesn't make sense to read from getInputStream()
when HTTP status code is greater than or equal to 400. It's not that simple, maybe you have to deal with some 3xx codes as well. Have a look at List of HTTP status codes.
A last word: if you find HttpURLConnection
cumbersome to use, you could use one of the abstraction libraries listed here.