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

dan*_*eln 11 java httpurlconnection

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

Caused by: java.io.IOException: Server returned HTTP response code: 412 for URL: <my url>
Run Code Online (Sandbox Code Playgroud)

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

我希望有一个选项来获取状态代码(即使它不是〜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
Run Code Online (Sandbox Code Playgroud)

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

rua*_*akh 7

我今天在工作中遇到了同样的问题——我们的代码被调用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()直接调用的代码行中。
    • 堆栈跟踪提到了后面的代码行,但我一开始没有注意到。

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


pia*_*ian 5

注意:这可能取决于您运行的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());
        }
    }
Run Code Online (Sandbox Code Playgroud)

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,混合模式)

在Windows 64位上

在此输入图像描述