如何从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.InputStreamResource
和org.springframework.core.io.ByteArrayResource
。 ByteArrayResource
本质上是byte[]
的包装器,因此以下代码将提供对作为字节数组的响应主体的访问:
Mono mono = client.get() ... .exchange() .flatMap(response -> response.bodyToMono(ByteArrayResource.class)) .map(ByteArrayResource::getByteArray);