【问题标题】:Okhttp3.14 Stream closedOkhttp3.14 流关闭
【发布时间】:2022-01-03 11:40:42
【问题描述】:

我在 3.14.9 版本中有一些关于 okhttp 的使用问题 如果我想为每个请求添加 LoggingInterceptor,我怎样才能得到响应体,它只能消耗一次?

接下来是我的尝试

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;
    }
}

会抛出stream关闭的异常,如何解决?

【问题讨论】:

    标签: okhttp


    【解决方案1】:

    为此使用peekBody

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

    【讨论】:

      【解决方案2】:

      我正在研究这个问题。我们可以使用缓冲区,在RequestBody-source-getBuffer中。

      工作代码如下:

          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;
          }
      

      【讨论】:

      • 我认为这使用了一些外部资源。 ObjectUtil,UTF8,日志。
      【解决方案3】:

      来自ernest-kiwele

      当响应正文在 try 块之外被读取时,将资源块与响应一起使用会导致此“关闭”问题:

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

      解决方法是重组代码以仅使用 try 块中的响应。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-05-01
        • 2019-09-03
        • 2020-05-14
        • 2016-11-24
        • 1970-01-01
        • 2015-06-24
        • 1970-01-01
        • 2014-04-09
        相关资源
        最近更新 更多