POST请求出现FileNotFoundException错误

5

POST请求返回URL的FileNotFoundException

在安卓系统中,我向https://nitos.gr Url发起了一个Http POST请求。

该url没有域名。因为Stackoverflow不允许在文本中包含数字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)。


不要打印错误流,而是读取它并打印错误流中的字符。这将有助于您。顺便说一句,您可以花些功夫格式化您的帖子,以便我们可以轻松阅读。 - hgoebl
1
抱歉,您是指仅打印字符吗? InputStream errorstream = con.getErrorStream();Log.w("GetErrorStream ", ""+errorstream); 这不对吗? - zoe vas
要使错误流可见,您必须以与稍后读取输入流内容(通过 BufferedReader)相同的方式处理它。然后您将看到服务器的响应。这只是更进一步了解您所犯的错误的微小一步... - hgoebl
2个回答

5
替换以下代码。
        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);
        }

换句话说,当HTTP状态码大于或等于400时,从getInputStream()读取是没有意义的。事情并不那么简单,你可能还需要处理一些3xx代码。请查看HTTP状态码列表
最后,如果您觉得HttpURLConnection难以使用,可以使用此处列出的抽象库之一。

你可以将 if (con.getResponseCode() / 100 == 2) 简化为 if *(con.getResponseCode() == 200)*。 - Ranjithkumar
不,这不是我想要的。它也应该对204为真(以204为例)。 - hgoebl
如果状态码不成功,从getInputStream()读取是有意义的。如果服务器在响应中发送更多信息怎么办?即使仅用于调试,查看响应正文也非常有用。 - Jans Rautenbach
1
@GeorgeRautenbach 你说得基本上是对的。但是你必须从con.getErrorStream()而不是con.getInputStream()读取。 - hgoebl

1
最终,由于服务器有身份验证,我无法执行POST请求。 因此,POST请求的配置没有问题。 因此,现在我应该找到一种方法将证书附加到对服务器的REST调用中。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接