簡體   English   中英

如何最好地從 Spring WebClient 的 ClientResponse 獲取字節數組?

[英]How to best get a byte array from a ClientResponse from Spring WebClient?

我正在使用響應式編程的代碼庫中嘗試使用 Spring 5 (5.0.0.RC2) 中的新WebClient ,並且我已經成功地將 JSON 響應從端點映射到我的應用程序中的 DTO,效果非常好:

WebClient client = WebClient.create(baseURI);
Mono<DTO> dto = client.get()
        .uri(uri)
        .accept(MediaType.APPLICATION_JSON)
        .exchange()
        .flatMap(response -> response.bodyToMono(DTO.class));

但是,現在我正在嘗試從使用協議緩沖區(二進制數據用作application/octet-stream )的端點獲取響應正文,因此我想從響應中獲取原始字節,然后將其映射自己一個對象。

我使用來自 Google Guava 的Bytes讓它像這樣工作:

Mono<byte[]> bytes = client.get()
        .uri(uri)
        .accept(MediaType.APPLICATION_OCTET_STREAM)
        .exchange()
        .flatMapMany(response -> response.body(BodyExtractors.toDataBuffers()))
        .map(dataBuffer -> {
            ByteBuffer byteBuffer = dataBuffer.asByteBuffer();
            byte[] byteArray = new byte[byteBuffer.remaining()];
            byteBuffer.get(byteArray, 0, bytes.length);
            return byteArray;
        })
        .reduce(Bytes::concat)

這是有效的,但是有沒有更簡單、更優雅的方法來獲取這些字節?

ClientResponse.bodyToMono()最終使用了一些聲稱支持指定類的org.springframework.core.codec.Decoder

所以我們應該檢查Decoder的類層次結構,特別是decodeToMono()方法的實現位置和方式。

有一個StringDecoder支持解碼為String ,一堆與 Jackson 相關的解碼器(在你的 DTO 示例中使用),還有一個ResourceDecoder是特別有趣的。

ResourceDecoder支持org.springframework.core.io.InputStreamResourceorg.springframework.core.io.ByteArrayResource ByteArrayResource本質上是byte[]的包裝器,因此以下代碼將提供對作為字節數組的響應主體的訪問:

Mono<byte[]> mono = client.get()
            ...
            .exchange()
            .flatMap(response -> response.bodyToMono(ByteArrayResource.class))
            .map(ByteArrayResource::getByteArray);

Oleg Estekhin 的回答為 OP 提供了他所要求的內容,但它將整個響應內容加載到內存中,這對於大型響應來說是一個問題。 要一次獲取一大塊字節,我們可以執行以下操作:

client.get()
  .uri("uri")
  .exchange()
  .flatMapMany { it.body(BodyExtractors.toDataBuffers()) }

默認情況下,這些緩沖區的大小為 8192 kb; 如果需要,請參閱答案以進行更改。

請注意,如果ByteBuffer不受數組支持,則嘗試執行dataBuffer.asByteBuffer().array()會引發異常。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM