Add DataBuffer BodyInserter/BodyExtractor
Added a BodyExtractor for Flux<DataBuffer>, and a BodyInserter for Publisher<DataBuffer> Issue: SPR-14918
This commit is contained in:
@@ -28,6 +28,7 @@ import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.HttpMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ReactiveHttpInputMessage;
|
||||
@@ -85,12 +86,24 @@ public abstract class BodyExtractors {
|
||||
*/
|
||||
public static <T> BodyExtractor<Flux<T>, ReactiveHttpInputMessage> toFlux(ResolvableType elementType) {
|
||||
Assert.notNull(elementType, "'elementType' must not be null");
|
||||
return (request, context) -> readWithMessageReaders(request, context,
|
||||
return (inputMessage, context) -> readWithMessageReaders(inputMessage, context,
|
||||
elementType,
|
||||
reader -> reader.read(elementType, request, Collections.emptyMap()),
|
||||
reader -> reader.read(elementType, inputMessage, Collections.emptyMap()),
|
||||
Flux::error);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code BodyExtractor} that returns the body of the message as a {@link Flux} of
|
||||
* {@link DataBuffer}s.
|
||||
* <p><strong>Note</strong> that the returned buffers should be released after usage by calling
|
||||
* {@link org.springframework.core.io.buffer.DataBufferUtils#release(DataBuffer)}
|
||||
* @return a {@code BodyExtractor} that returns the body
|
||||
* @see ReactiveHttpInputMessage#getBody()
|
||||
*/
|
||||
public static BodyExtractor<Flux<DataBuffer>, ReactiveHttpInputMessage> toDataBuffers() {
|
||||
return (inputMessage, context) -> inputMessage.getBody();
|
||||
}
|
||||
|
||||
private static <T, S extends Publisher<T>> S readWithMessageReaders(
|
||||
ReactiveHttpInputMessage inputMessage,
|
||||
BodyExtractor.Context context,
|
||||
|
||||
@@ -28,6 +28,7 @@ import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.core.ResolvableType;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.buffer.DataBuffer;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.ReactiveHttpOutputMessage;
|
||||
import org.springframework.http.server.reactive.ServerHttpResponse;
|
||||
@@ -182,16 +183,33 @@ public abstract class BodyInserters {
|
||||
Assert.notNull(eventsPublisher, "'eventsPublisher' must not be null");
|
||||
Assert.notNull(eventType, "'eventType' must not be null");
|
||||
return BodyInserter.of(
|
||||
(response, context) -> {
|
||||
(outputMessage, context) -> {
|
||||
HttpMessageWriter<T> messageWriter = sseMessageWriter(context);
|
||||
return messageWriter.write(eventsPublisher, eventType,
|
||||
MediaType.TEXT_EVENT_STREAM, response, Collections.emptyMap());
|
||||
MediaType.TEXT_EVENT_STREAM, outputMessage, Collections.emptyMap());
|
||||
|
||||
},
|
||||
() -> eventsPublisher
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@code BodyInserter} that writes the given {@code Publisher<DataBuffer>} to the
|
||||
* body.
|
||||
* @param publisher the data buffer publisher to write
|
||||
* @param <T> the type of the publisher
|
||||
* @return a {@code BodyInserter} that writes directly to the body
|
||||
* @see ReactiveHttpOutputMessage#writeWith(Publisher)
|
||||
*/
|
||||
public static <T extends Publisher<DataBuffer>> BodyInserter<T, ReactiveHttpOutputMessage> fromDataBuffers(T publisher) {
|
||||
Assert.notNull(publisher, "'publisher' must not be null");
|
||||
|
||||
return BodyInserter.of(
|
||||
(outputMessage, context) -> outputMessage.writeWith(publisher),
|
||||
() -> publisher
|
||||
);
|
||||
}
|
||||
|
||||
private static <T> HttpMessageWriter<T> sseMessageWriter(BodyInserter.Context context) {
|
||||
return context.messageWriters().get()
|
||||
.filter(messageWriter -> messageWriter
|
||||
|
||||
Reference in New Issue
Block a user