diff --git a/spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java index 1ebfe6bae0..045e90297f 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java +++ b/spring-web/src/main/java/org/springframework/web/accept/AbstractMappingContentNegotiationStrategy.java @@ -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; } diff --git a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManager.java b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManager.java index 3b910adcb8..1213161bc7 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManager.java +++ b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManager.java @@ -45,9 +45,6 @@ import org.springframework.web.context.request.NativeWebRequest; */ public class ContentNegotiationManager implements ContentNegotiationStrategy, MediaTypeFileExtensionResolver { - private static final List MEDIA_TYPE_ALL = Collections.singletonList(MediaType.ALL); - - private final List strategies = new ArrayList<>(); private final Set resolvers = new LinkedHashSet<>(); @@ -125,12 +122,12 @@ public class ContentNegotiationManager implements ContentNegotiationStrategy, Me public List resolveMediaTypes(NativeWebRequest request) throws HttpMediaTypeNotAcceptableException { for (ContentNegotiationStrategy strategy : this.strategies) { List 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 diff --git a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationStrategy.java index 6f998e73c4..b84569419d 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationStrategy.java +++ b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationStrategy.java @@ -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 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 */ diff --git a/spring-web/src/main/java/org/springframework/web/accept/HeaderContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/HeaderContentNegotiationStrategy.java index c758ea4bbe..96dd2ba536 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/HeaderContentNegotiationStrategy.java +++ b/spring-web/src/main/java/org/springframework/web/accept/HeaderContentNegotiationStrategy.java @@ -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 headerValues = Arrays.asList(headerValueArray); try { List mediaTypes = MediaType.parseMediaTypes(headerValues); MediaType.sortBySpecificityAndQuality(mediaTypes); - return mediaTypes; + return !CollectionUtils.isEmpty(mediaTypes) ? mediaTypes : MEDIA_TYPE_ALL_LIST; } catch (InvalidMediaTypeException ex) { throw new HttpMediaTypeNotAcceptableException( diff --git a/spring-web/src/test/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBeanTests.java b/spring-web/src/test/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBeanTests.java index d78c691b1b..5fd6cb1448 100644 --- a/spring-web/src/test/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBeanTests.java +++ b/spring-web/src/test/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBeanTests.java @@ -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. @@ -24,6 +24,7 @@ import java.util.Map; import org.junit.Before; import org.junit.Test; + import org.springframework.http.MediaType; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockServletContext; @@ -32,7 +33,7 @@ import org.springframework.web.HttpMediaTypeNotAcceptableException; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.ServletWebRequest; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; /** * Test fixture for {@link ContentNegotiationManagerFactoryBean} tests. @@ -74,13 +75,13 @@ public class ContentNegotiationManagerFactoryBeanTests { this.servletRequest.setRequestURI("/flower.foobarbaz"); assertEquals("Should ignore unknown extensions by default", - Collections.emptyList(), manager.resolveMediaTypes(this.webRequest)); + ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST, manager.resolveMediaTypes(this.webRequest)); this.servletRequest.setRequestURI("/flower"); this.servletRequest.setParameter("format", "gif"); assertEquals("Should not resolve request parameters by default", - Collections.emptyList(), manager.resolveMediaTypes(this.webRequest)); + ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST, manager.resolveMediaTypes(this.webRequest)); this.servletRequest.setRequestURI("/flower"); this.servletRequest.addHeader("Accept", MediaType.IMAGE_GIF_VALUE); @@ -179,7 +180,7 @@ public class ContentNegotiationManagerFactoryBeanTests { this.servletRequest.setRequestURI("/flower"); this.servletRequest.addHeader("Accept", MediaType.IMAGE_GIF_VALUE); - assertEquals(Collections.emptyList(), manager.resolveMediaTypes(this.webRequest)); + assertEquals(ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST, manager.resolveMediaTypes(this.webRequest)); } @Test diff --git a/spring-web/src/test/java/org/springframework/web/accept/MappingContentNegotiationStrategyTests.java b/spring-web/src/test/java/org/springframework/web/accept/MappingContentNegotiationStrategyTests.java index 67e05bbf21..926b4ad711 100644 --- a/spring-web/src/test/java/org/springframework/web/accept/MappingContentNegotiationStrategyTests.java +++ b/spring-web/src/test/java/org/springframework/web/accept/MappingContentNegotiationStrategyTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 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. @@ -53,7 +53,7 @@ public class MappingContentNegotiationStrategyTests { List mediaTypes = strategy.resolveMediaTypes(null); - assertEquals(0, mediaTypes.size()); + assertEquals(ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST, mediaTypes); } @Test @@ -63,7 +63,7 @@ public class MappingContentNegotiationStrategyTests { List mediaTypes = strategy.resolveMediaTypes(null); - assertEquals(0, mediaTypes.size()); + assertEquals(ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST, mediaTypes); } @Test diff --git a/spring-web/src/test/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategyTests.java b/spring-web/src/test/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategyTests.java index 401aad90e9..bd72a9fca9 100644 --- a/spring-web/src/test/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategyTests.java +++ b/spring-web/src/test/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategyTests.java @@ -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. @@ -29,8 +29,7 @@ import org.springframework.web.HttpMediaTypeNotAcceptableException; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.ServletWebRequest; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import static org.junit.Assert.*; /** * A test fixture for PathExtensionContentNegotiationStrategy. @@ -89,10 +88,12 @@ public class PathExtensionContentNegotiationStrategyTests { this.servletRequest.setContextPath("/project-1.0.0.M3"); this.servletRequest.setRequestURI("/project-1.0.0.M3/"); - assertTrue("Context path should be excluded", strategy.resolveMediaTypes(webRequest).isEmpty()); + assertEquals("Context path should be excluded", ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST, + strategy.resolveMediaTypes(webRequest)); this.servletRequest.setRequestURI("/project-1.0.0.M3"); - assertTrue("Context path should be excluded", strategy.resolveMediaTypes(webRequest).isEmpty()); + assertEquals("Context path should be excluded", ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST, + strategy.resolveMediaTypes(webRequest)); } // SPR-9390 @@ -118,7 +119,7 @@ public class PathExtensionContentNegotiationStrategyTests { PathExtensionContentNegotiationStrategy strategy = new PathExtensionContentNegotiationStrategy(); List mediaTypes = strategy.resolveMediaTypes(this.webRequest); - assertEquals(Collections.emptyList(), mediaTypes); + assertEquals(ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST, mediaTypes); } @Test(expected = HttpMediaTypeNotAcceptableException.class) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ProducesRequestCondition.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ProducesRequestCondition.java index 660b36106d..df84690ad4 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ProducesRequestCondition.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/ProducesRequestCondition.java @@ -259,8 +259,7 @@ public final class ProducesRequestCondition extends AbstractRequestCondition getAcceptedMediaTypes(HttpServletRequest request) throws HttpMediaTypeNotAcceptableException { - List mediaTypes = this.contentNegotiationManager.resolveMediaTypes(new ServletWebRequest(request)); - return mediaTypes.isEmpty() ? Collections.singletonList(MediaType.ALL) : mediaTypes; + return this.contentNegotiationManager.resolveMediaTypes(new ServletWebRequest(request)); } private int indexOfEqualMediaType(MediaType mediaType) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java index 36adce100e..807affee65 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/AbstractMessageConverterMethodProcessor.java @@ -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. @@ -365,8 +365,7 @@ public abstract class AbstractMessageConverterMethodProcessor extends AbstractMe private List getAcceptableMediaTypes(HttpServletRequest request) throws HttpMediaTypeNotAcceptableException { - List types = this.contentNegotiationManager.resolveMediaTypes(new ServletWebRequest(request)); - return (types.isEmpty() ? Collections.singletonList(MediaType.ALL) : types); + return this.contentNegotiationManager.resolveMediaTypes(new ServletWebRequest(request)); } /** diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java index 2c555203cc..d8bfc12916 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java @@ -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. @@ -253,11 +253,7 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport Assert.state(this.contentNegotiationManager != null, "No ContentNegotiationManager set"); try { ServletWebRequest webRequest = new ServletWebRequest(request); - List acceptableMediaTypes = this.contentNegotiationManager.resolveMediaTypes(webRequest); - acceptableMediaTypes = (!acceptableMediaTypes.isEmpty() ? acceptableMediaTypes : - Collections.singletonList(MediaType.ALL)); - List producibleMediaTypes = getProducibleMediaTypes(request); Set compatibleMediaTypes = new LinkedHashSet<>(); for (MediaType acceptable : acceptableMediaTypes) { diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurerTests.java index 30a1283730..bf2ef32d1c 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurerTests.java @@ -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. @@ -25,6 +25,7 @@ import org.junit.Test; import org.springframework.http.MediaType; import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.web.accept.ContentNegotiationManager; +import org.springframework.web.accept.ContentNegotiationStrategy; import org.springframework.web.accept.FixedContentNegotiationStrategy; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.context.request.ServletWebRequest; @@ -65,7 +66,7 @@ public class ContentNegotiationConfigurerTests { this.servletRequest.addParameter("format", "gif"); assertEquals("Should not resolve request parameters by default", - Collections.emptyList(), manager.resolveMediaTypes(this.webRequest)); + ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST, manager.resolveMediaTypes(this.webRequest)); this.servletRequest.setRequestURI("/flower"); this.servletRequest.addHeader("Accept", MediaType.IMAGE_GIF_VALUE); @@ -104,7 +105,7 @@ public class ContentNegotiationConfigurerTests { this.servletRequest.setRequestURI("/flower"); this.servletRequest.addHeader("Accept", MediaType.IMAGE_GIF_VALUE); - assertEquals(Collections.emptyList(), manager.resolveMediaTypes(this.webRequest)); + assertEquals(ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST, manager.resolveMediaTypes(this.webRequest)); } @Test