Запрос POST дает FileNotFoundException

Запрос POST выдает исключение FileNotFoundException для URL-адреса

Я делаю запрос POST Http к URL-адресу https://nitos.gr в андроид.

URL-адрес не имеет доменного имени. Stackoverflow не позволяет мне включать URL-адрес с цифрами в текст, поэтому я просто пишу случайный URL-адрес https://nitos.gr за пример.

Я получаю код ответа 400 и печатаю getErrorStream(), что дает libcore.net.http.UnknownLengthHttpInputStream@41eba330

Однако я успешно выполнил HTTP-запрос GET. URL-адрес https, поэтому у меня есть фальшивый менеджер доверия, разрешающий все соединения SSL.

В итоге:

Протокол: HTTPS

Запрос GET: выполнен успешно

Запрос POST: не выполнен

Код запроса: 400

Сообщение об ошибке: java.io.FileNotFoundException: https://nitos.gr

ErrorStream: java.io.FileNotFoundException: https://nitos.gr

Метод выполнения POST-запроса следующий:

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

    }

Сообщения об ошибках:

КОД ОТВЕТА (18936): код 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): в libcore.net.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:186)


comment
Не печатать поток ошибок, а читать его и печатать символы из потока ошибок. Это было бы здорово помочь вам. Кстати, вы могли бы приложить некоторые усилия, чтобы отформатировать свой пост, чтобы мы могли легко его прочитать.   -  person hgoebl    schedule 23.08.2014
comment
Извините, что вы подразумеваете под печатью только символов? InputStream errorstream = con.getErrorStream(); Log.w(GetErrorStream, +поток ошибок); Это неправильно?   -  person zoe vas    schedule 23.08.2014
comment
Чтобы сделать поток ошибок видимым, вы должны работать с ним так же, как позже вы читаете содержимое потока ввода (через BufferedReader). Затем вы увидите, что говорит сервер. Это будет всего лишь крошечный шаг, чтобы узнать, что вы сделали неправильно...   -  person hgoebl    schedule 24.08.2014


Ответы (2)


Замените следующий код

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

с участием

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

Или, другими словами: нет смысла читать из getInputStream(), когда код состояния HTTP больше или равен 400. Это не так просто, возможно, вам придется иметь дело и с некоторыми кодами 3xx. Посмотрите Список кодов состояния HTTP.

И последнее слово: если вы находите HttpURLConnection громоздким в использовании, вы можете использовать одну из библиотек абстракций, перечисленных здесь.

person hgoebl    schedule 24.08.2014
comment
вы можете упростить if (con.getResponseCode() / 100 == 2) до if (con.getResponseCode() == 200) - person Ranjith Kumar; 14.02.2017
comment
Нет, это не то, чего я хочу. Это должно быть верно и для 204 (в качестве примера). - person hgoebl; 14.02.2017
comment
имеет смысл читать из getInputStream(), если код состояния не успешен. Что, если сервер отправит дополнительную информацию вместе с ответом? Даже просто для отладки было бы здорово увидеть тело ответа. - person Jans Rautenbach; 19.07.2018
comment
@GeorgeRautenbach, ты в основном прав. Но вы должны читать из con.getErrorStream() вместо con.getInputStream(). - person hgoebl; 23.07.2018

Наконец, я не мог выполнить POST-запрос из-за того, что на сервере есть аутентификация. Таким образом, с настройкой POST-запроса проблем не возникает. Таким образом, теперь я должен найти способ прикрепить сертификат к вызову REST на сервер.

person zoe vas    schedule 26.08.2014