如何从Spring WebClient的ClientResponse中获取最佳字节数组?

我正在尝试从Spring 5(5.0.0.RC2)开始使用反应式编程的代码库中的新WebClient ,并且我已成功将JSON响应从端点映射到我的应用程序中的DTO,这非常好用:

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

但是,现在我正在尝试使用协议缓冲区(二进制数据作为application/octet-stream )的端点的响应体,所以我想从响应中获取原始字节,然后我将映射我自己的一个对象。

我使用Google Guava的Bytes让它像这样工作:

 Mono 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.ByteArrayResourceByteArrayResource本质上是byte[]的包装器,因此以下代码将提供对作为字节数组的响应主体的访问:

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