【问题标题】:POST Request gives FileNotFoundExceptionPOST 请求给出 FileNotFoundException
【发布时间】:2014-08-23 16:40:14
【问题描述】:

POST 请求为 URL 提供 FileNotFoundException

我正在向 android 中的 Url https://nitos.gr 发出 Http POST 请求。

该网址没有域名。 Stackoverflow 不允许我在文本中包含带有数字的 URL,所以我只是写了一个随机 url https://nitos.gr 作为示例。

我得到一个 400 响应代码,并打印 getErrorStream() 给 libcore.net.http.UnknownLengthHttpInputStream@41eba330

但是,我成功执行了 HTTP GET 请求。网址是 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)

【问题讨论】:

  • 不打印错误流,而是读取它并打印错误流中的字符。这对你很有帮助。顺便说一句,您可以花一些精力来格式化您的帖子,以便我们可以轻松阅读。
  • 对不起,你说的只打印字符是什么意思? InputStream 错误流 = con.getErrorStream(); Log.w("GetErrorStream", ""+errorstream);这不对吗?
  • 要使错误流可见,您必须像稍后读取输入流的内容一样处理它(通过BufferedReader)。然后你会看到服务器说什么。这只是进一步了解你做错了什么的一小步......

标签: android http-post httpurlconnection filenotfoundexception http-status-code-400


【解决方案1】:

替换以下代码

        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的代码。看看List of HTTP status codes

最后一句话:如果您觉得HttpURLConnection 使用起来很麻烦,您可以使用here 列出的抽象库之一。

【讨论】:

  • 你可以将 if (con.getResponseCode() / 100 == 2) 简化为 if (con.getResponseCode() == 200)
  • 不,这不是我想要的。 204 也应该是这样(例如)。
  • 如果状态码不成功,从getInputStream() 读取确实有意义。如果服务器通过响应发回更多信息怎么办?即使只是为了调试,看看响应体是什么也很棒。
  • @GeorgeRautenbach 你基本上是对的。但是您必须阅读 con.getErrorStream() 而不是 con.getInputStream()
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-22
    • 2021-09-26
    • 2018-12-14
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    • 2020-06-16
    • 2019-03-19
    相关资源
    最近更新 更多