Skip to content

Commit fda0885

Browse files
committed
Take content-type from ResponseEntity unconditionally
From #9a894a we began using the content-type from the ResponseEntity but cross-checking it still against the requested content type. Arguably there isn't any purpose in cross-checking. The only possible outcomes are: a) it's compatible or b) it's not, which would result in 406 (NOT_ACCEPTABLE). As we've been given explicitly the media type to use, it makes little sense to send 406, ignoring the wish to use that content type. Issue: SPR-16251
1 parent 203370a commit fda0885

File tree

2 files changed

+30
-26
lines changed

2 files changed

+30
-26
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/result/HandlerResultHandlerSupport.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ protected ReactiveAdapter getAdapter(HandlerResult result) {
116116
protected MediaType selectMediaType(ServerWebExchange exchange,
117117
Supplier<List<MediaType>> producibleTypesSupplier) {
118118

119+
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
120+
if (contentType != null && contentType.isConcrete()) {
121+
return contentType;
122+
}
123+
119124
List<MediaType> acceptableTypes = getAcceptableTypes(exchange);
120125
List<MediaType> producibleTypes = getProducibleTypes(exchange, producibleTypesSupplier);
121126

@@ -152,10 +157,6 @@ private List<MediaType> getAcceptableTypes(ServerWebExchange exchange) {
152157
private List<MediaType> getProducibleTypes(ServerWebExchange exchange,
153158
Supplier<List<MediaType>> producibleTypesSupplier) {
154159

155-
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
156-
if (contentType != null && contentType.isConcrete()) {
157-
return Collections.singletonList(contentType);
158-
}
159160
Set<MediaType> mediaTypes = exchange.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
160161
return (mediaTypes != null ? new ArrayList<>(mediaTypes) : producibleTypesSupplier.get());
161162
}

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
import java.util.Arrays;
2323
import java.util.Collections;
2424
import java.util.HashSet;
25-
import java.util.LinkedHashSet;
2625
import java.util.List;
2726
import java.util.Locale;
2827
import java.util.Set;
@@ -210,37 +209,41 @@ protected <T> void writeWithMessageConverters(@Nullable T value, MethodParameter
210209
}
211210
}
212211

213-
HttpServletRequest request = inputMessage.getServletRequest();
214-
List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(request);
215212

216-
MediaType contentType = outputMessage.getHeaders().getContentType();
217-
List<MediaType> producibleMediaTypes = (contentType != null && contentType.isConcrete() ?
218-
Collections.singletonList(contentType) : getProducibleMediaTypes(request, valueType, declaredType));
213+
List<MediaType> mediaTypesToUse;
219214

220-
if (outputValue != null && producibleMediaTypes.isEmpty()) {
221-
throw new HttpMessageNotWritableException("No converter found for return value of type: " + valueType);
215+
MediaType contentType = outputMessage.getHeaders().getContentType();
216+
if (contentType != null && contentType.isConcrete()) {
217+
mediaTypesToUse = Collections.singletonList(contentType);
222218
}
219+
else {
220+
HttpServletRequest request = inputMessage.getServletRequest();
221+
List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(request);
222+
List<MediaType> producibleMediaTypes = getProducibleMediaTypes(request, valueType, declaredType);
223223

224-
Set<MediaType> compatibleMediaTypes = new LinkedHashSet<>();
225-
for (MediaType requestedType : requestedMediaTypes) {
226-
for (MediaType producibleType : producibleMediaTypes) {
227-
if (requestedType.isCompatibleWith(producibleType)) {
228-
compatibleMediaTypes.add(getMostSpecificMediaType(requestedType, producibleType));
224+
if (outputValue != null && producibleMediaTypes.isEmpty()) {
225+
throw new HttpMessageNotWritableException(
226+
"No converter found for return value of type: " + valueType);
227+
}
228+
mediaTypesToUse = new ArrayList<>();
229+
for (MediaType requestedType : requestedMediaTypes) {
230+
for (MediaType producibleType : producibleMediaTypes) {
231+
if (requestedType.isCompatibleWith(producibleType)) {
232+
mediaTypesToUse.add(getMostSpecificMediaType(requestedType, producibleType));
233+
}
229234
}
230235
}
231-
}
232-
if (compatibleMediaTypes.isEmpty()) {
233-
if (outputValue != null) {
234-
throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes);
236+
if (mediaTypesToUse.isEmpty()) {
237+
if (outputValue != null) {
238+
throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes);
239+
}
240+
return;
235241
}
236-
return;
242+
MediaType.sortBySpecificityAndQuality(mediaTypesToUse);
237243
}
238244

239-
List<MediaType> mediaTypes = new ArrayList<>(compatibleMediaTypes);
240-
MediaType.sortBySpecificityAndQuality(mediaTypes);
241-
242245
MediaType selectedMediaType = null;
243-
for (MediaType mediaType : mediaTypes) {
246+
for (MediaType mediaType : mediaTypesToUse) {
244247
if (mediaType.isConcrete()) {
245248
selectedMediaType = mediaType;
246249
break;

0 commit comments

Comments
 (0)