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
This commit is contained in:
Rossen Stoyanchev 2017-12-02 00:27:15 -05:00
parent 203370a810
commit fda08852ba
2 changed files with 30 additions and 26 deletions

View File

@ -116,6 +116,11 @@ public abstract class HandlerResultHandlerSupport implements Ordered {
protected MediaType selectMediaType(ServerWebExchange exchange, protected MediaType selectMediaType(ServerWebExchange exchange,
Supplier<List<MediaType>> producibleTypesSupplier) { Supplier<List<MediaType>> producibleTypesSupplier) {
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
if (contentType != null && contentType.isConcrete()) {
return contentType;
}
List<MediaType> acceptableTypes = getAcceptableTypes(exchange); List<MediaType> acceptableTypes = getAcceptableTypes(exchange);
List<MediaType> producibleTypes = getProducibleTypes(exchange, producibleTypesSupplier); List<MediaType> producibleTypes = getProducibleTypes(exchange, producibleTypesSupplier);
@ -152,10 +157,6 @@ public abstract class HandlerResultHandlerSupport implements Ordered {
private List<MediaType> getProducibleTypes(ServerWebExchange exchange, private List<MediaType> getProducibleTypes(ServerWebExchange exchange,
Supplier<List<MediaType>> producibleTypesSupplier) { Supplier<List<MediaType>> producibleTypesSupplier) {
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
if (contentType != null && contentType.isConcrete()) {
return Collections.singletonList(contentType);
}
Set<MediaType> mediaTypes = exchange.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE); Set<MediaType> mediaTypes = exchange.getAttribute(HandlerMapping.PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE);
return (mediaTypes != null ? new ArrayList<>(mediaTypes) : producibleTypesSupplier.get()); return (mediaTypes != null ? new ArrayList<>(mediaTypes) : producibleTypesSupplier.get());
} }

View File

@ -22,7 +22,6 @@ import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Locale; import java.util.Locale;
import java.util.Set; import java.util.Set;
@ -210,37 +209,41 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe
} }
} }
HttpServletRequest request = inputMessage.getServletRequest();
List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(request); List<MediaType> mediaTypesToUse;
MediaType contentType = outputMessage.getHeaders().getContentType(); MediaType contentType = outputMessage.getHeaders().getContentType();
List<MediaType> producibleMediaTypes = (contentType != null && contentType.isConcrete() ? if (contentType != null && contentType.isConcrete()) {
Collections.singletonList(contentType) : getProducibleMediaTypes(request, valueType, declaredType)); mediaTypesToUse = Collections.singletonList(contentType);
if (outputValue != null && producibleMediaTypes.isEmpty()) {
throw new HttpMessageNotWritableException("No converter found for return value of type: " + valueType);
} }
else {
HttpServletRequest request = inputMessage.getServletRequest();
List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(request);
List<MediaType> producibleMediaTypes = getProducibleMediaTypes(request, valueType, declaredType);
Set<MediaType> compatibleMediaTypes = new LinkedHashSet<>(); if (outputValue != null && producibleMediaTypes.isEmpty()) {
for (MediaType requestedType : requestedMediaTypes) { throw new HttpMessageNotWritableException(
for (MediaType producibleType : producibleMediaTypes) { "No converter found for return value of type: " + valueType);
if (requestedType.isCompatibleWith(producibleType)) { }
compatibleMediaTypes.add(getMostSpecificMediaType(requestedType, producibleType)); mediaTypesToUse = new ArrayList<>();
for (MediaType requestedType : requestedMediaTypes) {
for (MediaType producibleType : producibleMediaTypes) {
if (requestedType.isCompatibleWith(producibleType)) {
mediaTypesToUse.add(getMostSpecificMediaType(requestedType, producibleType));
}
} }
} }
} if (mediaTypesToUse.isEmpty()) {
if (compatibleMediaTypes.isEmpty()) { if (outputValue != null) {
if (outputValue != null) { throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes);
throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes); }
return;
} }
return; MediaType.sortBySpecificityAndQuality(mediaTypesToUse);
} }
List<MediaType> mediaTypes = new ArrayList<>(compatibleMediaTypes);
MediaType.sortBySpecificityAndQuality(mediaTypes);
MediaType selectedMediaType = null; MediaType selectedMediaType = null;
for (MediaType mediaType : mediaTypes) { for (MediaType mediaType : mediaTypesToUse) {
if (mediaType.isConcrete()) { if (mediaType.isConcrete()) {
selectedMediaType = mediaType; selectedMediaType = mediaType;
break; break;