From fbdece6759682c24a69e513960155ea02f380b43 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Mon, 29 Sep 2025 09:21:20 +0100 Subject: [PATCH] Polishing in ResourceHttpMessageWriter See gh-35536 --- .../http/codec/ResourceHttpMessageWriter.java | 51 +++++++++++-------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/codec/ResourceHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/ResourceHttpMessageWriter.java index ddf10aa40f4..7c7e9573713 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/ResourceHttpMessageWriter.java +++ b/spring-web/src/main/java/org/springframework/http/codec/ResourceHttpMessageWriter.java @@ -51,12 +51,14 @@ import org.springframework.lang.Nullable; import org.springframework.util.MimeTypeUtils; /** - * {@code HttpMessageWriter} that can write a {@link Resource}. + * {@code HttpMessageWriter} that can write a {@link Resource} from both`` client + * and server perspectives. * - *

Also an implementation of {@code HttpMessageWriter} with support for writing one - * or more {@link ResourceRegion}'s based on the HTTP ranges specified in the request. + *

From a server perspective, the server-side only write method supports + * writing one or more {@link ResourceRegion}'s based on HTTP ranges specified + * in the request. * - *

For reading to a Resource, use {@link ResourceDecoder} wrapped with + *

To read a Resource, use {@link ResourceDecoder} wrapped with * {@link DecoderHttpMessageReader}. * * @author Arjen Poutsma @@ -122,16 +124,19 @@ public class ResourceHttpMessageWriter implements HttpMessageWriter { if (result != null) { return result; } - else { - Mono input = Mono.just(resource); - DataBufferFactory factory = message.bufferFactory(); - Flux body = this.encoder.encode(input, factory, type, message.getHeaders().getContentType(), hints) - .subscribeOn(Schedulers.boundedElastic()); - if (logger.isDebugEnabled()) { - body = body.doOnNext(buffer -> Hints.touchDataBuffer(buffer, hints, logger)); - } - return message.writeWith(body); + + Mono input = Mono.just(resource); + DataBufferFactory factory = message.bufferFactory(); + MediaType contentType = message.getHeaders().getContentType(); + + Flux body = this.encoder.encode(input, factory, type, contentType, hints) + .subscribeOn(Schedulers.boundedElastic()); + + if (logger.isDebugEnabled()) { + body = body.doOnNext(buffer -> Hints.touchDataBuffer(buffer, hints, logger)); } + + return message.writeWith(body); })); } @@ -139,7 +144,10 @@ public class ResourceHttpMessageWriter implements HttpMessageWriter { * Adds the default headers for the given resource to the given message. * @since 6.1 */ - public Mono addDefaultHeaders(ReactiveHttpOutputMessage message, Resource resource, @Nullable MediaType contentType, Map hints) { + public Mono addDefaultHeaders( + ReactiveHttpOutputMessage message, Resource resource, @Nullable MediaType contentType, + Map hints) { + return Mono.defer(() -> { HttpHeaders headers = message.getHeaders(); MediaType resourceMediaType = getResourceMediaType(contentType, resource, hints); @@ -149,16 +157,15 @@ public class ResourceHttpMessageWriter implements HttpMessageWriter { headers.set(HttpHeaders.ACCEPT_RANGES, "bytes"); } - if (headers.getContentLength() < 0) { - return lengthOf(resource) - .flatMap(contentLength -> { - headers.setContentLength(contentLength); - return Mono.empty(); - }); - } - else { + if (headers.getContentLength() >= 0) { return Mono.empty(); } + + return lengthOf(resource) + .flatMap(contentLength -> { + headers.setContentLength(contentLength); + return Mono.empty(); + }); }); }