【问题标题】:2.0.0: IllegalStateException: Cannot stream a request body without chunked encoding or a known content length2.0.0:IllegalStateException:无法在没有分块编码或已知内容长度的情况下流式传输请求正文
【发布时间】:2019-05-31 16:11:26
【问题描述】:

OkHttp 版本:2.0.0

我通过 Google Play 收到了以下异常堆栈跟踪:

java.lang.IllegalStateException: 无法流式传输请求正文 分块编码或已知的内容长度!在 com.squareup.okhttp.internal.http.HttpTransport.createRequestBody(HttpTransport.java:68) 在 com.squareup.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:254) 在 com.squareup.okhttp.Call.getResponse(Call.java:198) 在 com.squareup.okhttp.Call.access$200(Call.java:36) 在 com.squareup.okhttp.Call$AsyncCall.execute(Call.java:143) 在 com.squareup.okhttp.internal.NamedRunnable.run(NamedRunnable.java:33) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587) 在 java.lang.Thread.run(Thread.java:848)

这正是提出请求的方式:

Request.Builder requestBuilder = new Request.Builder();
requestBuilder.addHeader("User-Agent", userAgent);
requestBuilder.addHeader("Accept", "application/hal+json");
requestBuilder.url(transformedURL);

RequestBody requestBody = body == null ? null : RequestBody.create(MediaType.parse("application/json"), gson.toJson(body));
requestBuilder.method(method, requestBody);

okHttpClient.newCall(requestBuilder.build()).enqueue(new com.squareup.okhttp.Callback() { ...

起初它似乎与this bug 有关,但它已经被修复了。此外,我们在开发过程中多次测试了带有空主体的 POST 请求。
此应用仅执行 GET 和 POST 请求。

什么可能导致这个错误?

【问题讨论】:

  • 找到原因了吗?我遇到了同样的问题,但仍然不知道根本原因,因为我之前成功使用过相同的代码。

标签: java okhttp


【解决方案1】:

您是如何创建 HTTP 请求的?如果您可以创建可重现的测试用例,请向 OkHttp 提交错误,我们会修复。

【讨论】:

  • 谢谢杰西。我刚刚在上面添加了请求创建。我还没有设法重现它。迄今为止只报道过一次,发布后 2 周和数百名用户。
  • 您不应该在 POST 中使用空正文。那应该可以解决您的崩溃问题。我会争取早点让 OkHttp 投诉!
  • 我认为这不是问题所在。这个相同的应用程序已经使用空主体发出 POST 请求数周了,并且运行良好。另外,我在 HTTP RFC 上找不到这个“POST 请求需要正文”规则:tools.ietf.org/html/rfc7230#section-3.3
  • 正如我所怀疑的,POST 请求中的空正文是有效的,正如 HTTP RFC 第 3.3.2 节所建议的那样:For example, a Content-Length header field is normally sent in a POST request even when the value is 0 (indicating an empty payload body)
  • 当设备无法连接到代理服务器时,我似乎收到此错误。
【解决方案2】:

下面的代码抛出了这个异常:

打包好的http3.internal.http;

Http1xStream.java

  @Override public Sink createRequestBody(Request request, long contentLength) throws IOException {
    if ("chunked".equalsIgnoreCase(request.header("Transfer-Encoding"))) {
      // Stream a request body of unknown length.
      return newChunkedSink();
    }

    if (contentLength != -1) {
      // Stream a request body of a known length.
      return newFixedLengthSink(contentLength);
    }

    throw new IllegalStateException(
        "Cannot stream a request body without chunked encoding or a known content length!");
  }

为了解决这个问题,我需要在我的请求中添加一个标头,可以这样添加:.addHeader("Transfer-Encoding","chunked"):

OP 的示例:

Request.Builder requestBuilder = new Request.Builder();
requestBuilder.addHeader("User-Agent", userAgent);
requestBuilder.addHeader("Accept", "application/hal+json");

requestBuilder..addHeader("Transfer-Encoding","chunked")

requestBuilder.url(transformedURL);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-23
    • 2013-07-31
    • 2016-11-08
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    • 2012-02-07
    • 1970-01-01
    相关资源
    最近更新 更多