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,
Supplier<List<MediaType>> producibleTypesSupplier) {
MediaType contentType = exchange.getResponse().getHeaders().getContentType();
if (contentType != null && contentType.isConcrete()) {
return contentType;
}
List<MediaType> acceptableTypes = getAcceptableTypes(exchange);
List<MediaType> producibleTypes = getProducibleTypes(exchange, producibleTypesSupplier);
@ -152,10 +157,6 @@ public abstract class HandlerResultHandlerSupport implements Ordered {
private List<MediaType> getProducibleTypes(ServerWebExchange exchange,
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);
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.Collections;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
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();
List<MediaType> producibleMediaTypes = (contentType != null && contentType.isConcrete() ?
Collections.singletonList(contentType) : getProducibleMediaTypes(request, valueType, declaredType));
if (contentType != null && contentType.isConcrete()) {
mediaTypesToUse = Collections.singletonList(contentType);
}
else {
HttpServletRequest request = inputMessage.getServletRequest();
List<MediaType> requestedMediaTypes = getAcceptableMediaTypes(request);
List<MediaType> producibleMediaTypes = getProducibleMediaTypes(request, valueType, declaredType);
if (outputValue != null && producibleMediaTypes.isEmpty()) {
throw new HttpMessageNotWritableException("No converter found for return value of type: " + valueType);
throw new HttpMessageNotWritableException(
"No converter found for return value of type: " + valueType);
}
Set<MediaType> compatibleMediaTypes = new LinkedHashSet<>();
mediaTypesToUse = new ArrayList<>();
for (MediaType requestedType : requestedMediaTypes) {
for (MediaType producibleType : producibleMediaTypes) {
if (requestedType.isCompatibleWith(producibleType)) {
compatibleMediaTypes.add(getMostSpecificMediaType(requestedType, producibleType));
mediaTypesToUse.add(getMostSpecificMediaType(requestedType, producibleType));
}
}
}
if (compatibleMediaTypes.isEmpty()) {
if (mediaTypesToUse.isEmpty()) {
if (outputValue != null) {
throw new HttpMediaTypeNotAcceptableException(producibleMediaTypes);
}
return;
}
List<MediaType> mediaTypes = new ArrayList<>(compatibleMediaTypes);
MediaType.sortBySpecificityAndQuality(mediaTypes);
MediaType.sortBySpecificityAndQuality(mediaTypesToUse);
}
MediaType selectedMediaType = null;
for (MediaType mediaType : mediaTypes) {
for (MediaType mediaType : mediaTypesToUse) {
if (mediaType.isConcrete()) {
selectedMediaType = mediaType;
break;