Okhttp java.net.ProtocolException:意外的流结束

2024-10-02 20:39:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我目前正在开发Android应用程序,我正在使用okttp3发出一个简单的GET请求。我使用我的flask应用程序作为API端点。 编码Android

 OkHttpClient client = new OkHttpClient();

        final Request request = new Request.Builder()
                .url(url)
                .build();

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {

                    String s = response.body().string();
                    System.out.println(s);

            }

            @Override
            public void onFailure(@NotNull Call call, @NotNull IOException e) {

                System.out.println(e.getMessage());
            }

        });

代码瓶

@app.route('/abc', methods=["GET"])
def abc():
    return jsonify({"test": "abc"})

当我使用邮递员提出请求时,我没有任何问题: postman get request 然而,当使用上面的java代码时,有时它可以工作,但有时我会遇到以下错误

D/OkHttp: java.net.ProtocolException: unexpected end of stream
        at okhttp3.internal.http1.Http1ExchangeCodec$FixedLengthSource.read(Http1ExchangeCodec.kt:389)
        at okhttp3.internal.connection.Exchange$ResponseBodySource.read(Exchange.kt:276)
        at okio.Buffer.writeAll(Buffer.kt:1655)
        at okio.RealBufferedSource.readString(RealBufferedSource.kt:95)
        at okhttp3.ResponseBody.string(ResponseBody.kt:187)
        at com.example.teste.MainActivity$2.onResponse(MainActivity.java:83)
        at okhttp3.internal.connection.RealCall$AsyncCall.run(RealCall.kt:504)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
D/OkHttp:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at java.lang.Thread.run(Thread.java:764)

我曾尝试过在其他帖子中提出的多种解决方案,如:

OkHttpClient client = new OkHttpClient.Builder()
    .retryOnConnectionFailure(true)
    .build();

Request request = new Request.Builder()
                    .addHeader("Authorization", "Bearer " + apiToken)
                    .addHeader("content-type", "application/json")
                    .addHeader("Connection","close")
                    .url(uri)
                    .build();

但它们都不起作用。这里有什么问题?我尝试过用其他虚拟api的相同代码发出请求,但它总是有效的。我丢失了什么

错误发生在这里:

val read = super.read(sink, minOf(bytesRemaining, byteCount))
      if (read == -1L) {
        connection.noNewExchanges() // The server didn't supply the promised content length.
        val e = ProtocolException("unexpected end of stream")
        responseBodyComplete()
        throw e
      }

它与服务器提供的内容长度有关。我如何解决这个问题


Tags: buildclienturlnewreadrequestbuilderjava
2条回答

为每个请求添加一个拦截器并添加Connection-Close头怎么样?如下

okHttpClient = new OkHttpClient.Builder()
        .addNetworkInterceptor(new Interceptor() {
            @Override
            public Response intercept(Chain chain) throws IOException {
                Request request = chain.request().newBuilder().addHeader("Connection", "close").build();
                return chain.proceed(request);
            }
        })
        .build();

HTTP/1.1 defines the "close" connection option for the sender to signal that the connection will be closed after completion of the response. For example,

Connection: close in either the request or the response header fields indicates that the connection SHOULD NOT be considered `persistent' (section 8.1) after the current request/response is complete.

HTTP/1.1 applications that do not support persistent connections MUST include the "close" connection option in every message.

只有在我使用仿真器时才会发生异常。在设备上没有问题

相关问题 更多 >