zack zhang
zack zhang

Reputation: 21

Okhttp3.14 Stream closed

I have some usage issue about okhttp in 3.14.9 release if i want add LoggingInterceptor for each request, how can i get response body, which can only consume once?

And follow is my attemp

public class LoggingRequestInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request request = chain.request();
        Response response = chain.proceed(request);
        
        log.debug(
                "{}, {}, {}, {}, {}, {}, {}",
                request.url(),
                request.method(),
                JSONUtil.toJsonStr(request.body()),
                request.headers(),
                dup.body() == null ? null : dup.body().string());

        return response;
    }
}

It will throw exception of stream closed, how to fix it?

Upvotes: 2

Views: 969

Answers (3)

dfrankow
dfrankow

Reputation: 21407

From ernest-kiwele:

Using a try with a resources block with the response causes this "closed" problem when the response body is read outside of the try block:

try (Response response = client.newCall(request.build()).execute()) {
    return response;
} //response.close() called implicitly by the JVM

The fix is to restructure the code to only use the response within the try block.

Upvotes: 0

Yuri Schimke
Yuri Schimke

Reputation: 13458

Use peekBody for this

  val client = OkHttpClient.Builder()
    .addInterceptor {
      val response = it.proceed(it.request())
      println(response.peekBody(1000000).string())
      response
    }
    .build()

Upvotes: 1

zack zhang
zack zhang

Reputation: 21

I do research for this issue. We can use buffer, which is in RequestBody-source-getBuffer.

Working code is below:

    public String getResponseBody(Response response) {

        try {
            ResponseBody responseBody = response.body();
            if (!ObjectUtil.isNull(responseBody)) {
                BufferedSource source = responseBody.source();
                source.request(Long.MAX_VALUE);
                Buffer buffer = source.getBuffer();
                return buffer.clone().readString(UTF8);
            }
        } catch (IOException e) {
            log.error("get response body failed: ", e);
        }

        return null;
    }

Upvotes: 0

Related Questions