Add DataBuffer BodyInserter/BodyExtractor

Added a BodyExtractor for Flux<DataBuffer>, and a BodyInserter for
Publisher<DataBuffer>

Issue: SPR-14918
This commit is contained in:
Arjen Poutsma
2016-11-24 16:45:32 +01:00
parent b22a59a0c4
commit 735e288d46
4 changed files with 80 additions and 7 deletions

View File

@@ -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,

View File

@@ -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