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); 
相关问题