How to stream binary data in a response body in Spring WebFlux

ESala :

I am making a project using Spring WebFlux.

In the past I had used StreamingResponseBody for streaming responses back to the client, but I can't find the equivalent in WebFlux.

Example:

import org.springframework.web.servlet.mvc.method.annotation.StreamingResponseBody;

@GetMapping("/video")
public StreamingResponseBody stream() {
    InputStream videoStream = ...
    StreamingResponseBody res = (os) -> { IOUtils.copy(videoStream, os); }
    return res;
}

Is there an equivalent of StreamingResponseBody for WebFlux? or, should I import the traditional Spring MVC and mix them?

Edit: So far I am solving it by accessing the ServerHttpResponse (example below). But I am still wondering about better solutions.

@GetMapping("/video")
fun stream2(response: ServerHttpResponse): Mono<Void> {
    val factory = response.bufferFactory()
    val publisher = videoStream
            .observeVideoParts()
            .map { factory.wrap(it.bytes) }
    return response.writeWith(publisher)
}
ESala :

For now, the best solution that I have found is to return a ServerHttpResponse.

Since ServerHttpResponse only allows to write DataBuffer objects but not ByteArray objects, I made an extension function that wraps them before writing:

fun ServerHttpResponse.writeByteArrays(bytes: Flux<ByteArray>): Mono<Void> {
    val factory = this.bufferFactory()
    val dataBuffers = bytes.map { factory.wrap(it) }
    return this.writeWith(dataBuffers)
}

Then a Flux<ByteArray> can simply be written like this:

@GetMapping("/video")
fun stream2(response: ServerHttpResponse): Mono<Void> {
    val videoParts: Flux<ByteArray> = ...
    return response.writeByteArrays(videoParts)
}

I am still open to other solutions.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=462535&siteId=1