当代码已知时,HttpURLConnection.getResponseCode()会抛出IOException

时间:2014-02-24 14:31:52

标签: java httpurlconnection

即使状态已知,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具体相关。

2 个答案:

答案 0 :(得分:5)

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

答案在HttpURLConnection的源代码中,并且与所有错误代码&gt;的错误有关。 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

我在http://media.jarnbjo.de/412.php上的测试使用:

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

<64>在Windows 64位

enter image description here

答案 1 :(得分: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()的代码行,尽管我们的实际问题是稍后在我们的代码行中直接致电getInputStream()
    • stacktrace 提到了后面的代码行,但是起初我没有注意到。

我敢打赌,你的案子也是一样。