Kamil
Kamil

Reputation: 245

OKHttp response fail: java.lang.IllegalStateException: closed

I request to link for getting JSON but response.body().string() value always have an error. Another way, I split response.body().string() to response.body() and string but Android studio don't find ResponseBody. 2 way doesn't work. Please help!

String doGetRequest(String url) throws IOException {
       Request request = new Request.Builder()
            .url(url)
            .build();

    try (Response response = client.newCall(request).execute()) {
        System.out.println(response.body().string());
        //ResponseBody responseBody = response.body();
        //String content = responseBody.string();
        //System.out.println(content);
        return response.body().string();
    }
}

Upvotes: 20

Views: 19243

Answers (3)

Mahdi Zareei
Mahdi Zareei

Reputation: 2066

maybe you are closing your response in an interceptor like this

override fun intercept(chain: Interceptor.Chain): Response {
//...
val response = chain.proceed(builder.build())
response.close()
//...
}

Upvotes: 1

Mark Kazakov
Mark Kazakov

Reputation: 1116

This happens because .string() can be called only once

You can solve the issue in the following way (Java):

ResponseBody responseBodyCopy = response.peekBody(Long.MAX_VALUE);
responseBodyCopy.string();

By copying the response body you avoid using .string() twice

Upvotes: 15

Vikalp Patel
Vikalp Patel

Reputation: 10887

response.body().string() → You can only call string() once.

Because response body can be huge so OkHttp doesn’t store it in memory, it reads it as a stream from the network when you need it.

When you read the body as a string() OkHttp downloads response body and returns it to you without keeping the reference to the string, it can’t be downloaded twice without new request.

You are calling it more than once.

try(..){
    System.out.println(response.body().string());// once
    return response.body().string();`// twice
 }

You can save response in variable by calling it once then use that variable for further usage.

try(..){
  String responseData = response.body().string();//Be cautious about memory constraint here.
  System.out.println(responseData);
  return responseData;`
}

Upvotes: 37

Related Questions