Take advantage of Encoder#encodeValue

EncoderHttpMessageWriter takes advantage of the Encoder#encodeValue
that's new in 5.2 in order to produce a Mono<DataBuffer> instead of
producing a Flux<DataBuffer> and then using flux.singleOrEmpty().

Closes gh-22952
This commit is contained in:
Rossen Stoyanchev
2019-05-15 17:31:59 -04:00
parent 013249757a
commit ed2a3bd451
3 changed files with 50 additions and 31 deletions

View File

@@ -29,8 +29,8 @@ import org.springframework.core.codec.AbstractEncoder;
import org.springframework.core.codec.Encoder;
import org.springframework.core.codec.Hints;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferFactory;
import org.springframework.core.io.buffer.PooledDataBuffer;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpLogging;
import org.springframework.http.MediaType;
import org.springframework.http.ReactiveHttpOutputMessage;
@@ -114,24 +114,24 @@ public class EncoderHttpMessageWriter<T> implements HttpMessageWriter<T> {
MediaType contentType = updateContentType(message, mediaType);
Flux<DataBuffer> body = this.encoder.encode(
inputStream, message.bufferFactory(), elementType, contentType, hints);
if (inputStream instanceof Mono) {
HttpHeaders headers = message.getHeaders();
return body
.singleOrEmpty()
return Mono.from(inputStream)
.switchIfEmpty(Mono.defer(() -> {
headers.setContentLength(0);
message.getHeaders().setContentLength(0);
return message.setComplete().then(Mono.empty());
}))
.flatMap(buffer -> {
headers.setContentLength(buffer.readableByteCount());
.flatMap(value -> {
DataBufferFactory factory = message.bufferFactory();
DataBuffer buffer = this.encoder.encodeValue(value, factory, elementType, contentType, hints);
message.getHeaders().setContentLength(buffer.readableByteCount());
return message.writeWith(Mono.just(buffer)
.doOnDiscard(PooledDataBuffer.class, PooledDataBuffer::release));
});
}
Flux<DataBuffer> body = this.encoder.encode(
inputStream, message.bufferFactory(), elementType, contentType, hints);
if (isStreamingMediaType(contentType)) {
return message.writeAndFlushWith(body.map(buffer ->
Mono.just(buffer).doOnDiscard(PooledDataBuffer.class, PooledDataBuffer::release)));

View File

@@ -103,4 +103,4 @@ public class PathPatternRouteMatcher implements RouteMatcher {
}
}
}
}