Refine ContentNegotiationStrategy contract

Consistently return "*/*" if no media types were requested rather than
an empty list. Existing code has to check for both in any case to see
if nothing was requested.

Issue: SPR-16624
This commit is contained in:
Rossen Stoyanchev
2018-03-27 16:32:18 -04:00
parent 9a27bc9b3e
commit f3994467c4
11 changed files with 44 additions and 40 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2017 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -122,7 +122,7 @@ public abstract class AbstractMappingContentNegotiationStrategy extends MappingM
return Collections.singletonList(mediaType);
}
}
return Collections.emptyList();
return MEDIA_TYPE_ALL_LIST;
}

View File

@@ -45,9 +45,6 @@ import org.springframework.web.context.request.NativeWebRequest;
*/
public class ContentNegotiationManager implements ContentNegotiationStrategy, MediaTypeFileExtensionResolver {
private static final List<MediaType> MEDIA_TYPE_ALL = Collections.singletonList(MediaType.ALL);
private final List<ContentNegotiationStrategy> strategies = new ArrayList<>();
private final Set<MediaTypeFileExtensionResolver> resolvers = new LinkedHashSet<>();
@@ -125,12 +122,12 @@ public class ContentNegotiationManager implements ContentNegotiationStrategy, Me
public List<MediaType> resolveMediaTypes(NativeWebRequest request) throws HttpMediaTypeNotAcceptableException {
for (ContentNegotiationStrategy strategy : this.strategies) {
List<MediaType> mediaTypes = strategy.resolveMediaTypes(request);
if (mediaTypes.isEmpty() || mediaTypes.equals(MEDIA_TYPE_ALL)) {
if (mediaTypes.equals(MEDIA_TYPE_ALL_LIST)) {
continue;
}
return mediaTypes;
}
return Collections.emptyList();
return MEDIA_TYPE_ALL_LIST;
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,7 @@
package org.springframework.web.accept;
import java.util.Collections;
import java.util.List;
import org.springframework.http.MediaType;
@@ -31,11 +32,20 @@ import org.springframework.web.context.request.NativeWebRequest;
@FunctionalInterface
public interface ContentNegotiationStrategy {
/**
* A singleton list with {@link MediaType#ALL} that is returned from
* {@link #resolveMediaTypes} when no specific media types are requested.
* @since 5.0.5
*/
List<MediaType> MEDIA_TYPE_ALL_LIST = Collections.singletonList(MediaType.ALL);
/**
* Resolve the given request to a list of media types. The returned list is
* ordered by specificity first and by quality parameter second.
* @param webRequest the current request
* @return the requested media types or an empty list (never {@code null})
* @return the requested media types, or {@link #MEDIA_TYPE_ALL_LIST} if none
* were requested.
* @throws HttpMediaTypeNotAcceptableException if the requested media
* types cannot be parsed
*/

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2016 the original author or authors.
* Copyright 2002-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,12 +17,12 @@
package org.springframework.web.accept;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.springframework.http.HttpHeaders;
import org.springframework.http.InvalidMediaTypeException;
import org.springframework.http.MediaType;
import org.springframework.util.CollectionUtils;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.context.request.NativeWebRequest;
@@ -45,14 +45,14 @@ public class HeaderContentNegotiationStrategy implements ContentNegotiationStrat
String[] headerValueArray = request.getHeaderValues(HttpHeaders.ACCEPT);
if (headerValueArray == null) {
return Collections.emptyList();
return MEDIA_TYPE_ALL_LIST;
}
List<String> headerValues = Arrays.asList(headerValueArray);
try {
List<MediaType> mediaTypes = MediaType.parseMediaTypes(headerValues);
MediaType.sortBySpecificityAndQuality(mediaTypes);
return mediaTypes;
return !CollectionUtils.isEmpty(mediaTypes) ? mediaTypes : MEDIA_TYPE_ALL_LIST;
}
catch (InvalidMediaTypeException ex) {
throw new HttpMediaTypeNotAcceptableException(