HttpURLConnection.getResponseCode() выдает IOException, когда код известен
Как получилось, что 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
UPDATE
Я изменил реализацию на стороне сервера, чтобы вернуть другой код состояния (303), и теперь он работает (не бросая исключение IOException). Это означает, что это связано с 412.
Ответы
Ответ 1
ВНИМАНИЕ: это может зависеть от версии 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 (сборка 1.7.0_21-b11)
Java HotSpot (TM) 64-разрядная серверная VM (сборка 23.21-b01, смешанный режим)
в Windows 64 бит
![enter image description here]()
Ответ 2
Я столкнулся с той же проблемой сегодня на работе - наш код вызывал HttpURLConnection.getResponseCode()
и заканчивался Caused by: java.io.IOException: Server returned HTTP response code: 400 for URL:...
- и через некоторое время качества Окунувшись в исходный код JDK, я понял следующее:
-
getResponseCode()
самом деле не вызывает исключение! - Исключение
getResponseCode()
изнутри getResponseCode()
, но оно перехватывается. - До того, как он перехватил, в
HttpURLConnection
устанавливаются некоторые поля, которые позволяют getResponseCode()
успешно, что и происходит. - Также до того, как оно было перехвачено, исключение сохраняется в поле в подклассе
HttpURLConnection
(в частности: sun.net.www.protocol.http.HttpURLConnection.rememberedException
).
- Впоследствии наш код вызвал
getInputStream()
напрямую, что в данном случае должно вызвать исключение. (getErrorStream()
этого вы должны вызывать getErrorStream()
.) -
getInputStream()
генерирует исключение, которое оборачивает исходное выброшенное и перехваченное исключение. - Таким образом, в итоге мы получили трассировку стека с параметром
Caused by
который ссылался на нашу строку кода, где мы Caused by
getResponseCode()
, хотя наша настоящая проблема была позже, в нашей строке кода, где мы getInputStream()
напрямую. - В трассировке стека также упоминается более поздняя строка кода, но сначала я этого не заметил.
Могу поспорить, что ваш случай был таким же.