What is the best way to get an array of bytes from ClientResponse from Spring WebClient?

I am testing a new WebClient from Spring 5 (5.0.0.RC2) in a code base using reactive programming, and I have had a successful mapping of the JSON response to the endpoint on the DTO in my application, which works very well:

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

However, now I am trying to get the response body from an endpoint using protocol buffers (binary data that are served as application/octet-stream ), so I would like to get the raw bytes from the response, which I then map the object to itself.

I decided that this would work using Bytes from Google Guava:

 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) 

This works, but is there an easier and more elegant way to get these bytes?

+5
source share
1 answer

ClientResponse.bodyToMono() at the end uses some org.springframework.core.codec.Decoder , which claims to support the specified class.

So, we need to check the hierarchy of Decoder classes, in particular, where and how the decodeToMono() method is implemented.

There is a StringDecoder that supports decoding to String , a set of Jackson-related decoders (used in your example DTO under the hood), and there is also a ResourceDecoder that is of particular interest.

ResourceDecoder supports org.springframework.core.io.InputStreamResource and org.springframework.core.io.ByteArrayResource . ByteArrayResource is essentially a wrapper around byte[] , so the following code will provide access to the response body as an array of bytes:

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

Source: https://habr.com/ru/post/1269319/


All Articles