Add HEAD support in MVC/WebFlux Resource handling

This commit introduces explicit HEAD support in Spring
MVC's ResourceHttpRequestHandler and WebFlux's ResourceWebHandler,
adding just headers but no body.

Closes gh-28291
This commit is contained in:
Arjen Poutsma
2022-04-07 13:51:21 +02:00
parent df5e3f79e1
commit 9adfa5e8b0
6 changed files with 54 additions and 19 deletions

View File

@@ -116,8 +116,27 @@ public class ResourceHttpMessageWriter implements HttpMessageWriter<Resource> {
private Mono<Void> writeResource(Resource resource, ResolvableType type, @Nullable MediaType mediaType,
ReactiveHttpOutputMessage message, Map<String, Object> hints) {
addHeaders(message, resource, mediaType, hints);
return zeroCopy(resource, null, message, hints)
.orElseGet(() -> {
Mono<Resource> input = Mono.just(resource);
DataBufferFactory factory = message.bufferFactory();
Flux<DataBuffer> body = this.encoder.encode(input, factory, type, message.getHeaders().getContentType(), hints);
if (logger.isDebugEnabled()) {
body = body.doOnNext(buffer -> Hints.touchDataBuffer(buffer, hints, logger));
}
return message.writeWith(body);
});
}
/**
* Adds the default headers for the given resource to the given message.
* @since 6.0
*/
public void addHeaders(ReactiveHttpOutputMessage message, Resource resource, @Nullable MediaType contentType, Map<String, Object> hints) {
HttpHeaders headers = message.getHeaders();
MediaType resourceMediaType = getResourceMediaType(mediaType, resource, hints);
MediaType resourceMediaType = getResourceMediaType(contentType, resource, hints);
headers.setContentType(resourceMediaType);
if (headers.getContentLength() < 0) {
@@ -126,17 +145,7 @@ public class ResourceHttpMessageWriter implements HttpMessageWriter<Resource> {
headers.setContentLength(length);
}
}
return zeroCopy(resource, null, message, hints)
.orElseGet(() -> {
Mono<Resource> input = Mono.just(resource);
DataBufferFactory factory = message.bufferFactory();
Flux<DataBuffer> body = this.encoder.encode(input, factory, type, resourceMediaType, hints);
if (logger.isDebugEnabled()) {
body = body.doOnNext(buffer -> Hints.touchDataBuffer(buffer, hints, logger));
}
return message.writeWith(body);
});
headers.set(HttpHeaders.ACCEPT_RANGES, "bytes");
}
private static MediaType getResourceMediaType(

View File

@@ -122,6 +122,14 @@ public class ResourceHttpMessageConverter extends AbstractHttpMessageConverter<R
return (contentLength < 0 ? null : contentLength);
}
/**
* Adds the default headers for the given resource to the given message.
* @since 6.0
*/
public void addDefaultHeaders(HttpOutputMessage message, Resource resource, @Nullable MediaType contentType) throws IOException {
addDefaultHeaders(message.getHeaders(), resource, contentType);
}
@Override
protected void writeInternal(Resource resource, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {