【问题标题】:HttpURLConnection.getResponseCode() throws IOException when code is known当代码已知时,HttpURLConnection.getResponseCode() 抛出 IOException
【发布时间】:2014-03-26 06:54:21
【问题描述】:

即使状态已知,HttpURLConnection.getResponseCode() 怎么会抛出 IOException

Caused by: java.io.IOException: Server returned HTTP response code: 412 for URL: <my url>

获取响应码不是问题,因为它是写在异常消息中的。

我希望有一个选项来获取状态代码(即使它不是 ~200)而不会出现异常,因此我将能够在我的代码中决定要做什么。

完整的堆栈跟踪:

Caused by: java.io.IOException: Server returned HTTP response code: 412 for URL: <my url>
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1625)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:468)
... my code

更新 我更改了服务器端实现以返回不同的状态代码(303),它现在正在工作(不抛出 IOException)。这意味着它与 412 特别相关。

【问题讨论】:

  • 你检查过服务器可能有什么问题吗? en.wikipedia.org/wiki/…
  • 什么意思?服务器正常工作并按预期返回 412。我希望能够从连接中获取状态代码而不会引发异常。
  • 我无法回答原因,但可以考虑使用更复杂的 HTTP 客户端。
  • 你能显示完整的堆栈跟踪吗?
  • @Smutje 如果状态代码是异常消息的一部分,这意味着连接能够获取状态代码,那怎么可能。

标签: java httpurlconnection


【解决方案1】:

我今天在工作中遇到了同样的问题——我们的代码调用了 HttpURLConnection.getResponseCode() 并以 Caused by: java.io.IOException: Server returned HTTP response code: 400 for URL: ... 结束——经过一段时间深入研究 JDK 源代码后,我最终弄清楚了以下问题:

  • getResponseCode() 并没有实际上抛出异常!
  • getResponseCode() 内部深处抛出异常,但它被捕获。
    • 在它被捕获之前,HttpURLConnection 中设置了一些字段,允许 getResponseCode() 成功,它确实如此。
    • 同样在它被捕获之前,异常被保存到HttpURLConnection 的子类中的一个字段中(特别是:sun.net.www.protocol.http.HttpURLConnection.rememberedException)。
  • 随后,我们的代码直接调用了getInputStream(),在这种情况下应该抛出异常。 (您应该改为致电 getErrorStream()。)
  • getInputStream() 抛出一个异常,该异常包装原始抛出并捕获的异常。
  • 所以我们最终得到了一个带有Caused by-s 的堆栈跟踪,它引用了我们调用getResponseCode() 的代码行,尽管我们的实际问题是在稍后我们调用@987654334 的代码行中@ 直接地。
    • 堆栈跟踪提到了后面的代码行,但一开始我没有注意到。

我敢打赌你的情况是一样的。

【讨论】:

    【解决方案2】:

    注意:这可能取决于您运行的 JVM 版本!!!因为@SotiriosDelimanolis 的测试给出了不同的结果

    答案在 HttpURLConnection 的源代码中,并且与所有错误代码 > 400 的错误有关

    如果错误代码等于 404 或 410,则抛出 FileNotFoundException,否则抛出 IOException

        if (respCode >= 400) {
            if (respCode == 404 || respCode == 410) {
                throw new FileNotFoundException(url.toString());
            } else {
                throw new java.io.IOException("Server returned HTTP" +
                  " response code: " + respCode + " for URL: " +
                  url.toString());
            }
        }
    

    sun.net.www.protocol.http.HttpURLConnection 1625行源代码:

    http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/net/www/protocol/http/HttpURLConnection.java#HttpURLConnection

    我对@9​​87654322@ 的测试使用:

    Java(TM) SE 运行时环境(内部版本 1.7.0_21-b11) Java HotSpot(TM) 64 位服务器 VM(内部版本 23.21-b01,混合模式)

    在 Windows 64 位上

    【讨论】:

    • 我们已经在之前已删除的答案中检查过这一点。这不应该发生。你可以自己测试一下。
    • 这取决于您使用的 sdk...这是来自 openjdk 7。您在什么 jdk 上进行了测试?
    • 这不是我要告诉你的。使用HttpURLConnectionmedia.jarnbjo.de/412.php 发送HTTP GET 请求。你不会得到例外。您将获得 412 状态码。
    • 好的,让我看看,你用的是什么jvm?
    • 请注意您如何使用getInputStream() 而不是getResponseCode()。 OP 的错误在getResponseCode()
    猜你喜欢
    • 2013-04-26
    • 1970-01-01
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 2012-06-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多