Issue
Learning about HTTP requests in Java. I'd like to know if reading the response body is essential to keeping a connection alive.
Here's an example code block (which posts a message to some URL):
private void writeToConnection(String url, String msg) throws IOException {
try {
HttpURLConnection connection = open(url);
// "Try with resources"
try (BufferedWriter writer = new BufferedWriter(
new OutputStreamWriter(connection.getOutputStream()))) {
writer.write(msg);
}
// Why do I need this line?
IOUtils.readStringFromStream(connection.getInputStream());
int code = connection.getResponseCode();
System.out.println(String.format("Returned response code %d.", code));
} catch (IOException e) {
e.printStackTrace();
}
}
Why is it necessary to read the input stream? The method readStringFromStream
is returning a string but the string is not being assigned to anything. Does this ensure the connection stays alive? If so, how does the connection stay alive when the first line in the method opens a new connection? If the next batch of data to be written invokes this method, wouldn't that discard the old connection and open a new one?
Solution
I believe the intent of this code is indeed to consume the response body so that the connection can be reused. However, I'm not sure that this approach is correct; it is also likely to depend on the version of Java you are using.
First, it should suffice to get the connection's InputStream
and close it; behind the scenes, the body still needs to be read, but closing the stream signals to the connection handler that the application wants to skip the body, and the handler can read and discard the content before putting the connection into a cache for re-use.
However, depending on the status, there could be an error stream instead of an input stream. Even in this case, the body needs to be consumed before the connection can be re-used, but many applications (like this one) don't bother reading the body of an error message. Since Java 7, however, if the error body is small enough, it will be consumed and buffered automatically.
Behind the scenes, a connection cache is used to retain open connections. Although the method names suggest a new connection is opened every time, in fact the cache is first checked for an open connection.
Answered By - erickson
Answer Checked By - Terry (JavaFixing Volunteer)