HttpURLConnection.getResponseCode() 在代码已知时抛出 IOException

2022-09-03 07:06:34

即使状态已知,为什么还会抛出?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特别相关。


答案 1

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

  • getResponseCode() 实际上并没有引发异常!
  • 一个异常从内心深处被抛出,但它被抓住了。getResponseCode()
    • 在它被捕获之前,一些字段被设置在里面,允许成功,它确实如此。HttpURLConnectiongetResponseCode()
    • 同样在捕获之前,异常将保存到 的子类中的字段(特别是:)。HttpURLConnectionsun.net.www.protocol.http.HttpURLConnection.rememberedException
  • 随后,我们的代码直接调用,在这种情况下应该会引发异常。(你应该打电话来代替。getInputStream()getErrorStream()
  • getInputStream()引发一个异常,该异常将包装原始引发并捕获的异常。
  • 因此,我们最终得到了一个带有 -s 的堆栈跟踪,它引用了我们调用的代码行,即使我们的实际问题是后来,在我们直接调用的代码行中。Caused bygetResponseCode()getInputStream()
    • 堆栈跟踪提到了后面的代码行,但我一开始没有注意到这一点。

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


答案 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

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

Java(TM) SE Runtime Environment (build 1.7.0_21-b11) Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)

在 Windows 64 位上

enter image description here


推荐