android - 使用空负载解析 HTTP 202 - java.io.EOFException - Android、Retrofit、Gson
问题描述
想法:我正在尝试在 Android 上使用一个端点。调用它后,端点将返回 HTTP 202(空正文,根本没有有效负载)几次,当数据准备好时,它将返回 HTTP 200 和数据。
我想要做的是能够解析 202 响应,但由于它没有有效负载,我将检查状态并在需要时再次轮询,一旦我得到 200 OK,我将解析并使用数据.
我解析和使用 200 OK 响应的部分正在工作,但解析 202 响应不起作用,我得到了异常(见下文)。
我知道有几种方法可以解决这个问题:
- 使用 Void 作为返回类型,
- 使用 ResponseBody 作为返回类型,
- 使用 Converter.Factory。
我为此创建了一个转换器类:
internal val nullOnEmptyConverterFactory = object : Converter.Factory() {
fun converterFactory() = this
override fun responseBodyConverter(
type: Type,
annotations: Array<out Annotation>,
retrofit: Retrofit
) = object : Converter<ResponseBody, Any?> {
val nextResponseBodyConverter =
retrofit.nextResponseBodyConverter<Any?>(converterFactory(), type, annotations)
override fun convert(value: ResponseBody) =
if (value.contentLength() != 0L) nextResponseBodyConverter.convert(value) else null
}
}
这就是我使用它的方式:
return Retrofit.Builder()
.client(client)
.addConverterFactory(nullOnEmptyConverterFactory)
.addConverterFactory(ScalarsConverterFactory.create()) // used for jsonp
.addConverterFactory(GsonConverterFactory.create(factory))
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.baseUrl(ApiService.getBaseUrl())
.build()
这是我得到的错误:
error: java.io.EOFException
at okio.RealBufferedSource.require(RealBufferedSource.kt:55)
at okio.GzipSource.consumeHeader(GzipSource.kt:104)
at okio.GzipSource.read(GzipSource.kt:62)
at okio.RealBufferedSource.read(RealBufferedSource.kt:41)
at okio.ForwardingSource.read(ForwardingSource.kt:29)
at retrofit2.OkHttpCall$ExceptionCatchingResponseBody$1.read(OkHttpCall.java:288)
at okio.RealBufferedSource.select(RealBufferedSource.kt:93)
at okhttp3.internal.Util.readBomAsCharset(Util.kt:256)
at okhttp3.ResponseBody$BomAwareReader.read(ResponseBody.kt:208)
at com.google.gson.stream.JsonReader.fillBuffer(JsonReader.java:1295)
at com.google.gson.stream.JsonReader.nextNonWhitespace(JsonReader.java:1333)
at com.google.gson.stream.JsonReader.consumeNonExecutePrefix(JsonReader.java:1576)
at com.google.gson.stream.JsonReader.doPeek(JsonReader.java:534)
at com.google.gson.stream.JsonReader.peek(JsonReader.java:425)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:207)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:39)
at retrofit2.converter.gson.GsonResponseBodyConverter.convert(GsonResponseBodyConverter.java:27)
at data.network.util.NullOnEmptyConverterFactoryKt$nullOnEmptyConverterFactory$1$responseBodyConverter$1.convert(NullOnEmptyConverterFactory.kt:22)
at data.network.util.NullOnEmptyConverterFactoryKt$nullOnEmptyConverterFactory$1$responseBodyConverter$1.convert(NullOnEmptyConverterFactory.kt:17)
at retrofit2.OkHttpCall.parseResponse(OkHttpCall.java:225)
at retrofit2.OkHttpCall$1.onResponse(OkHttpCall.java:121)
at okhttp3.RealCall$AsyncCall.run(RealCall.kt:138)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
解决方案
找出造成这种情况的原因:上面提到的库、Retrofit、GSon 都没有问题。如果您跟踪堆栈跟踪,您会发现它指向一个问题,即响应不符合 gzip 文件格式。
如果您使用 gzip 文件格式,OkHttp 库期望响应具有 10 字节的标头。如果响应没有它,则库会引发异常。
在这种情况下,API 有问题。
帮助我弄清楚问题的票。
推荐阅读
- c - C:指向函数的指针,该函数返回指向整数的指针
- vb6 - 带有空格的 Visual Basic 6.0 Shell 命令
- javascript - 显示后关闭 jQueryUI 对话框并在新的浏览器窗口中打开页面
- reactjs - 仅在第一次尝试使用 react 和 redux 登录时保存登录尝试并打开抽屉
- tensorflow - Google提供的Posenet模型中实现了哪篇论文
- qt - Youtube 直播视频流在 qtwebengine 中不起作用
- android - 无法在 iOS 模拟器中打开 expo 客户端 2.16.1 版
- typescript - 循环遍历枚举数组的打字稿奇怪行为
- apache-spark - 如何使用 sql 查询而不是 api 覆盖列
- python - 如何计算将在 Python 中打印的下一个字符串的长度?