POST Request gives FileNotFoundException

zoe vas picture zoe vas · Aug 23, 2014 · Viewed 6.9k times · Source

POST request gives FileNotFoundException for the URL

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();
            }

    }

The error messages:

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)

Answer

hgoebl picture hgoebl · Aug 24, 2014

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.