How come HttpURLConnection.getResponseCode()
throws IOException
even if the status is known?
Caused by: java.io.IOException: Server returned HTTP response code: 412 for URL: <my url>
It's not a problem of getting the response code because it is written in the exception message.
I would expect to have an option to get the status code (even if it's not ~200) without getting an exception, so I'll be able to decide in my code what to do.
Full stack trace:
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 I changed the server side implementation to return a different status code (303), and it's working now (not throwing IOException). Meaning it is specifically related to 412.
Set the request method in HttpURLConnection instance, default value is GET. Call setRequestProperty() method on HttpURLConnection instance to set request header values, such as “User-Agent” and “Accept-Language” etc. We can call getResponseCode() to get the response HTTP code.
We can create an HttpUrlConnection instance using the openConnection() method of the URL class. Note that this method only creates a connection object but doesn't establish the connection yet.
I encountered the same problem today at work — our code was calling HttpURLConnection.getResponseCode()
and ending up with Caused by: java.io.IOException: Server returned HTTP response code: 400 for URL: ...
— and after some quality time diving through the JDK source code, I ended up figuring out the following:
getResponseCode()
isn't actually throwing an exception!getResponseCode()
, but it gets caught.
HttpURLConnection
that allow getResponseCode()
to succeed, which it does.HttpURLConnection
(specifically: sun.net.www.protocol.http.HttpURLConnection.rememberedException
).getInputStream()
directly, which is supposed to throw an exception in this case. (You're supposed to call getErrorStream()
instead.)getInputStream()
throws an exception that wraps the original thrown-and-caught exception.Caused by
-s that referred to our line of code where we were calling getResponseCode()
, even though our actual issue was later, in our line of code where we were calling getInputStream()
directly.
I'm betting that your case was the same.
ATTENTION: this may depend on the JVM version you are running!!! as tests of @SotiriosDelimanolis gave different results
The answer is in the source code of the HttpURLConnection and is related to all the errors that have error code > 400
If error code is equal 404 or 410 a FileNotFoundException is thrown else an IOException as
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 Source code at line 1625:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/net/www/protocol/http/HttpURLConnection.java#HttpURLConnection
My test on http://media.jarnbjo.de/412.php using :
Java(TM) SE Runtime Environment (build 1.7.0_21-b11) Java HotSpot(TM) 64-Bit Server VM (build 23.21-b01, mixed mode)
on Windows 64 bit
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With