5

我試用了Spring 5(5.0.0.RC2)中使用響應式編程的代碼庫中的新WebClient,並且我已成功將JSON響應從端點映射到應用程序中的DTO,這非常有效不錯:如何從Spring WebClient的ClientResponse中獲取最佳字節數組?

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)端點響應主體,所以我想擺脫的響應,原始字節,這然後我會自己映射到一個對象。

我得到了它這樣使用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) 

這工作,但有一個更簡單,更優雅的方式來獲得這些字節?

回答

8

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

所以我們應該檢查Decoder的類層次結構,特別是在何處以及如何實現decodeToMono()方法。

有一個StringDecoder支持解碼到String,一堆傑克遜相關的解碼器(在您的DTO示例中使用),還有一個特別感興趣的ResourceDecoder

ResourceDecoder支持org.springframework.core.io.InputStreamResourceorg.springframework.core.io.ByteArrayResourceByteArrayResource基本上圍繞byte[]的包裝,所以下面的代碼將提供給響應身體的接入作爲字節數組:

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