Загрузка большого результата
Можно ли использовать декларативный клиент для загрузки большого результата, например, используя InputStream
? Я пробовал подпись клиента как
HttpResponse<InputStream> getQueryResult(String jobId, String resultId);
Но он пытается загрузить все тело, что затем приводит к
io.micronaut.http.client.exceptions.ContentLengthExceededException: The received length exceeds the maximum content length
Заранее спасибо.
1 ответ
Здесь происходит то, что ваш клиент запрашивает полностью полученный (агрегированный) HttpResponse, оборачивая байтовый массив, который затем преобразуется в InputStream. Чтобы получить байты ответа без агрегирования, вам необходимо запросить один из реактивных типов, например org.reactivestreams.Publisher
(или его подходящий подкласс) ByteBuffer
s. Тогда вам нужно обработать их.
Пример:
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!
}
(Очевидно, что блокирование плохо для высокой пропускной способности, но это только пример)
Надеюсь, это поможет.