Accessing body string of an OkHttp Response twice results in IllegalStateException: closed

Solution 1:

Update:

As mugwort points out there is a simpler, more lightweight API available now (see GitHub issue):

String responseBodyString = response.peekBody(Long.MAX_VALUE).string();
Log.d("TAG", responseBodyString);

Original Answer:

For explanation of the issue see Greg Ennis' answer.

However, if you can not easily pass the result in a variable, but still need to access the response body twice you have another option:

Clone the buffer before reading it. By that the original buffer is neither emptied nor closed. See this snippet:

ResponseBody responseBody = response.body();
BufferedSource source = responseBody.source();
source.request(Long.MAX_VALUE); // request the entire body.
Buffer buffer = source.buffer();
// clone buffer before reading from it
String responseBodyString = buffer.clone().readString(Charset.forName("UTF-8"))
Log.d("TAG", responseBodyString);

This approach is used in HttpLoggingInterceptor in project okhttp by square themselves.

Solution 2:

The string method on the response will read the input (network) stream and convert it into a string. So it dynamically builds the string and returns it to you. The second time you call it, the network stream has already been consumed and is no longer available.

You should save the result of string into a String variable, and then access it as many times as needed.

Solution 3:

ResponseBody body = response.peekBody(Long.MAX_VALUE);
String content = body.string();
//do something

this code get the response body and won't consume the buffer. it is a new api added in this issue