下载大结果
Downloading large result
是否可以使用声明式客户端下载大型结果,例如使用 InputStream
?我尝试了
这样的客户端签名
HttpResponse<InputStream> getQueryResult(String jobId, String resultId);
但它试图下载整个主体,然后导致
io.micronaut.http.client.exceptions.ContentLengthExceededException: The received length exceeds the maximum content length
提前致谢。
这里发生的是您的客户端请求一个完全接收的(聚合的)HttpResponse,包装一个字节数组,然后将其转换为 InputStream。为了在不聚合的情况下获得响应字节,您需要请求一种反应类型,例如 ByteBuffer
的 org.reactivestreams.Publisher
(或其合适的子类)。然后你需要处理这些。
示例:
Flowable<ByteBuffer<?>> getQueryResult(String jobId, String resultId);
然后您可以 运行 map
、forEach
、blockingForEach
等 io.reactivex.Flowable
- 但请记住释放缓冲区,否则您会产生大量垃圾,并获得令人讨厌的日志消息。示例(在 Groovy 中):
Flowable<ByteBuffer<?>> responseFlowable = myClient.getQueryResult("job1", "foo")
int sum = 0
responseFlowable.blockingForEach { ByteBuffer byteBuffer ->
sum += byteBuffer.toByteArray().count('!')
((ReferenceCounted)byteBuffer).release() // Let Netty do its thing!
}
(显然,阻塞对高吞吐量不利,但这只是一个例子)
希望对您有所帮助。
是否可以使用声明式客户端下载大型结果,例如使用 InputStream
?我尝试了
HttpResponse<InputStream> getQueryResult(String jobId, String resultId);
但它试图下载整个主体,然后导致
io.micronaut.http.client.exceptions.ContentLengthExceededException: The received length exceeds the maximum content length
提前致谢。
这里发生的是您的客户端请求一个完全接收的(聚合的)HttpResponse,包装一个字节数组,然后将其转换为 InputStream。为了在不聚合的情况下获得响应字节,您需要请求一种反应类型,例如 ByteBuffer
的 org.reactivestreams.Publisher
(或其合适的子类)。然后你需要处理这些。
示例:
Flowable<ByteBuffer<?>> getQueryResult(String jobId, String resultId);
然后您可以 运行 map
、forEach
、blockingForEach
等 io.reactivex.Flowable
- 但请记住释放缓冲区,否则您会产生大量垃圾,并获得令人讨厌的日志消息。示例(在 Groovy 中):
Flowable<ByteBuffer<?>> responseFlowable = myClient.getQueryResult("job1", "foo")
int sum = 0
responseFlowable.blockingForEach { ByteBuffer byteBuffer ->
sum += byteBuffer.toByteArray().count('!')
((ReferenceCounted)byteBuffer).release() // Let Netty do its thing!
}
(显然,阻塞对高吞吐量不利,但这只是一个例子)
希望对您有所帮助。