在连接错误时改进OkHttp流的意外结束

时间:2019-05-02 10:16:54

标签: android https retrofit2 okhttp okhttp3

我正在使用以下依赖项(Retrofit和OkHttp)。

implementation 'com.squareup.retrofit2:retrofit:2.3.0'
implementation 'com.squareup.retrofit2:converter-gson:2.3.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.3.0'
implementation 'com.squareup.okhttp3:okhttp:3.10.0'
implementation 'com.squareup.okhttp3:logging-interceptor:3.10.0'

下面是我的代码:

OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .addInterceptor(cache_interceptor)
                .cache(cache)
                .connectTimeout(AppConstants.TIME_OUT, TimeUnit.SECONDS)
                .readTimeout(AppConstants.TIME_OUT, TimeUnit.SECONDS)
                .writeTimeout(AppConstants.TIME_OUT, TimeUnit.SECONDS)
                .connectionSpecs(Collections.singletonList(ConnectionSpec.CLEARTEXT))
                .retryOnConnectionFailure(false)
                .build();

return new Retrofit.Builder()
                .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
                .client(okHttpClient)
                .addConverterFactory(ScalarsConverterFactory.create())
                .addConverterFactory(GsonConverterFactory.create())
                .baseUrl(BuildConfig.BASE_URL).build();

private final Interceptor cache_interceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {

            Request request = chain.request().newBuilder().addHeader("Connection", "close").build();
            return chain.proceed(request);
        }
    };
  

URL是 https ,指向 AWS S3 实例。

但是我遇到了https URL端点的错误。

  

java.io.IOException:意外终止流   连接{s3.amazonaws.com:443,代理=直接   hostAddress = s3.amazonaws.com / XX.XXX.XXX.XX:443 cipherSuite = none   protocol = http / 1.1}

通过类似的线程,如Github discussion 1Github discussion 2,但找不到解决方法。

  

如果我将 https 替换为 http ,也不会出现问题或错误!

知道导致问题的原因是什么

3 个答案:

答案 0 :(得分:2)

我已经编辑了问题一个多月了,并给其他人贴上笔记以提供有效答案。到目前为止,SO尚未提供解决方案,我正在写下解决方案以供将来参考。

尽管以下内容并非我想要的,但我可以避免OkHttpClient来获得预期的响应!

这是我提到的版本。相同的问题 在将来的版本中可能会或不会出现。

是的,您没有看错。避免使用OkHttpClient并尝试单独使用Retrofit

return new Retrofit.Builder()
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BuildConfig.BASE_URL).build();

即使这阻止了获取HTTP日志,我仍然能够 获得 HTTP HTTPS 的成功响应。

答案 1 :(得分:0)

意外终止流主要是由于API响应中提到的“ Content-Length”与API的实际大小不匹配而引起的。如果他正在覆盖内容长度,请更好地与您的后端开发人员联系。

答案 2 :(得分:0)

由于我已经使用HttpURLConnection和OkHttp3进行了尝试,因此我将做出贡献,因为所有Apache东西都已被弃用..并且两种方法都出现“关闭”连接错误。 我有一个要测试的简单bash CGI脚本。我按照那里的所有教程进行操作,钻研了自签名证书,标头中的utf-8参数,将连接设置为关闭(再次是标头设置),传递“内容长度”等)。 (所有值得的努力,但不是让我熬夜的4个晚上)。 我能够连接(我可以在服务器端看到发生了什么事),但是每当我尝试从堆栈中弹出内容以读取结果时,我都会得到连接错误。 我的bash CGI非常简单。 “内容类型:text / html;”和空行以及一些输出,例如“ hello world”(均可通过浏览器运行)。 所以。我的建议,因为对此没有任何文档或帮助。将您的应用指向google.com。如果您的应用程序没有错误,那么我会押注甜甜圈,这是服务器端的问题。 就我而言(对我而言,这毫无意义,但确实如此),所有解决方案都没有显示出这些应用程序方法期望网页上的所有内容,这意味着“头”和“ body”,并添加“ html”以取得良好效果。

仅仅是因为您的浏览器会正确显示它,所以不能保证api库可以很好地处理它,所以我将重复说明。.将您的应用程序指向一个可以合理地格式化格式的网络源,然后从那里拿走。