diff --git a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc index a8cc9756dec..5ed0bfa3810 100644 --- a/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc +++ b/framework-docs/modules/ROOT/pages/web/webmvc/mvc-controller/ann-requestmapping.adoc @@ -248,36 +248,6 @@ specific than other pattern that do not have double wildcards. For the full details, follow the above links to the pattern Comparators. -[[mvc-ann-requestmapping-suffix-pattern-match]] -== Suffix Match - -Starting in 5.3, by default Spring MVC no longer performs `.{asterisk}` suffix pattern -matching where a controller mapped to `/person` is also implicitly mapped to -`/person.{asterisk}`. As a consequence path extensions are no longer used to interpret -the requested content type for the response -- for example, `/person.pdf`, `/person.xml`, -and so on. - -Using file extensions in this way was necessary when browsers used to send `Accept` headers -that were hard to interpret consistently. At present, that is no longer a necessity and -using the `Accept` header should be the preferred choice. - -Over time, the use of file name extensions has proven problematic in a variety of ways. -It can cause ambiguity when overlain with the use of URI variables, path parameters, and -URI encoding. Reasoning about URL-based authorization -and security (see next section for more details) also becomes more difficult. - -To completely disable the use of path extensions in versions prior to 5.3, set the following: - -* `useSuffixPatternMatching(false)`, see xref:web/webmvc/mvc-config/path-matching.adoc[PathMatchConfigurer] -* `favorPathExtension(false)`, see xref:web/webmvc/mvc-config/content-negotiation.adoc[ContentNegotiationConfigurer] - -Having a way to request content types other than through the `"Accept"` header can still -be useful, for example, when typing a URL in a browser. A safe alternative to path extensions is -to use the query parameter strategy. If you must use file extensions, consider restricting -them to a list of explicitly registered extensions through the `mediaTypes` property of -xref:web/webmvc/mvc-config/content-negotiation.adoc[ContentNegotiationConfigurer]. - - [[mvc-ann-requestmapping-rfd]] == Suffix Match and RFD 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 89f01c57b1b..ed3189bc68f 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-2023 the original author or authors. + * Copyright 2002-2024 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. @@ -83,8 +83,7 @@ public abstract class AbstractMappingContentNegotiationStrategy extends MappingM /** * Whether to ignore requests with unknown file extension. Setting this to * {@code false} results in {@code HttpMediaTypeNotAcceptableException}. - *

By default this is set to {@literal false} but is overridden in - * {@link PathExtensionContentNegotiationStrategy} to {@literal true}. + *

By default, this is set to {@literal false}. */ public void setIgnoreUnknownExtensions(boolean ignoreUnknownExtensions) { this.ignoreUnknownExtensions = ignoreUnknownExtensions; 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 b4eb5c6cd8d..dec192ca158 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 @@ -139,17 +139,6 @@ public class ContentNegotiationManager implements ContentNegotiationStrategy, Me return doResolveExtensions(resolver -> resolver.resolveFileExtensions(mediaType)); } - /** - * {@inheritDoc} - *

At startup this method returns extensions explicitly registered with - * either {@link PathExtensionContentNegotiationStrategy} or - * {@link ParameterContentNegotiationStrategy}. At runtime if there is a - * "path extension" strategy and its - * {@link PathExtensionContentNegotiationStrategy#setUseRegisteredExtensionsOnly(boolean) - * useRegisteredExtensionsOnly} property is set to "false", the list of extensions may - * increase as file extensions are resolved via - * {@link org.springframework.http.MediaTypeFactory} and cached. - */ @Override public List getAllFileExtensions() { return doResolveExtensions(MediaTypeFileExtensionResolver::getAllFileExtensions); diff --git a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java index 91bc8b3a9c2..11f499271ef 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java +++ b/spring-web/src/main/java/org/springframework/web/accept/ContentNegotiationManagerFactoryBean.java @@ -23,8 +23,6 @@ import java.util.Locale; import java.util.Map; import java.util.Properties; -import jakarta.servlet.ServletContext; - import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.http.MediaType; @@ -32,7 +30,6 @@ import org.springframework.http.MediaTypeFactory; import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; -import org.springframework.web.context.ServletContextAware; /** * Factory to create a {@code ContentNegotiationManager} and configure it with @@ -56,12 +53,6 @@ import org.springframework.web.context.ServletContextAware; * Off * * - * {@link #setFavorPathExtension favorPathExtension} - * false (as of 5.3) - * {@link PathExtensionContentNegotiationStrategy} - * Off - * - * * {@link #setIgnoreAcceptHeader ignoreAcceptHeader} * false * {@link HeaderContentNegotiationStrategy} @@ -85,20 +76,11 @@ import org.springframework.web.context.ServletContextAware; * methods and set the exact strategies to use via * {@link #setStrategies(List)}. * - *

Deprecation Note: As of 5.2.4, - * {@link #setFavorPathExtension(boolean) favorPathExtension} and - * {@link #setIgnoreUnknownPathExtensions(boolean) ignoreUnknownPathExtensions} - * are deprecated in order to discourage using path extensions for content - * negotiation and for request mapping with similar deprecations on - * {@link org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping - * RequestMappingHandlerMapping}. For further context, please read issue - * #24719. * @author Rossen Stoyanchev * @author Brian Clozel * @since 3.2 */ -public class ContentNegotiationManagerFactoryBean - implements FactoryBean, ServletContextAware, InitializingBean { +public class ContentNegotiationManagerFactoryBean implements FactoryBean, InitializingBean { @Nullable private List strategies; @@ -108,12 +90,8 @@ public class ContentNegotiationManagerFactoryBean private String parameterName = "format"; - private boolean favorPathExtension = false; - private final Map mediaTypes = new HashMap<>(); - private boolean ignoreUnknownPathExtensions = true; - @Nullable private Boolean useRegisteredExtensionsOnly; @@ -125,9 +103,6 @@ public class ContentNegotiationManagerFactoryBean @Nullable private ContentNegotiationManager contentNegotiationManager; - @Nullable - private ServletContext servletContext; - /** * Set the exact list of strategies to use. @@ -161,30 +136,12 @@ public class ContentNegotiationManagerFactoryBean this.parameterName = parameterName; } - /** - * Whether the path extension in the URL path should be used to determine - * the requested media type. - *

By default this is set to {@code false} in which case path extensions - * have no impact on content negotiation. - * @deprecated as of 5.2.4. See class-level note on the deprecation of path - * extension config options. As there is no replacement for this method, - * in 5.2.x it is necessary to set it to {@code false}. In 5.3 the default - * changes to {@code false} and use of this property becomes unnecessary. - */ - @Deprecated - public void setFavorPathExtension(boolean favorPathExtension) { - this.favorPathExtension = favorPathExtension; - } - /** * Add a mapping from a key to a MediaType where the key are normalized to * lowercase and may have been extracted from a path extension, a filename * extension, or passed as a query parameter. *

The {@link #setFavorParameter(boolean) parameter strategy} requires - * such mappings in order to work while the {@link #setFavorPathExtension(boolean) - * path extension strategy} can fall back on lookups via - * {@link ServletContext#getMimeType} and - * {@link org.springframework.http.MediaTypeFactory}. + * such mappings in order to work. *

Note: Mappings registered here may be accessed via * {@link ContentNegotiationManager#getMediaTypeMappings()} and may be used * not only in the parameter and path extension strategies. For example, @@ -227,35 +184,10 @@ public class ContentNegotiationManagerFactoryBean } /** - * Whether to ignore requests with path extension that cannot be resolved - * to any media type. Setting this to {@code false} will result in an - * {@code HttpMediaTypeNotAcceptableException} if there is no match. - *

By default this is set to {@code true}. - * @deprecated as of 5.2.4. See class-level note on the deprecation of path - * extension config options. - */ - @Deprecated - public void setIgnoreUnknownPathExtensions(boolean ignore) { - this.ignoreUnknownPathExtensions = ignore; - } - - /** - * Indicate whether to use the Java Activation Framework as a fallback option - * to map from file extensions to media types. - * @deprecated as of 5.0, in favor of {@link #setUseRegisteredExtensionsOnly(boolean)}, - * which has reverse behavior. - */ - @Deprecated - public void setUseJaf(boolean useJaf) { - setUseRegisteredExtensionsOnly(!useJaf); - } - - /** - * When {@link #setFavorPathExtension favorPathExtension} or - * {@link #setFavorParameter(boolean)} is set, this property determines + * When {@link #setFavorParameter(boolean)} is set, this property determines * whether to use only registered {@code MediaType} mappings or to allow * dynamic resolution, for example, via {@link MediaTypeFactory}. - *

By default this is not set in which case dynamic resolution is on. + *

By default, this is not set in which case dynamic resolution is on. */ public void setUseRegisteredExtensionsOnly(boolean useRegisteredExtensionsOnly) { this.useRegisteredExtensionsOnly = useRegisteredExtensionsOnly; @@ -303,14 +235,6 @@ public class ContentNegotiationManagerFactoryBean this.defaultNegotiationStrategy = strategy; } - /** - * Invoked by Spring to inject the ServletContext. - */ - @Override - public void setServletContext(ServletContext servletContext) { - this.servletContext = servletContext; - } - @Override public void afterPropertiesSet() { @@ -321,7 +245,6 @@ public class ContentNegotiationManagerFactoryBean * Create and initialize a {@link ContentNegotiationManager} instance. * @since 5.0 */ - @SuppressWarnings("deprecation") public ContentNegotiationManager build() { List strategies = new ArrayList<>(); @@ -329,20 +252,6 @@ public class ContentNegotiationManagerFactoryBean strategies.addAll(this.strategies); } else { - if (this.favorPathExtension) { - PathExtensionContentNegotiationStrategy strategy; - if (this.servletContext != null && !useRegisteredExtensionsOnly()) { - strategy = new ServletPathExtensionContentNegotiationStrategy(this.servletContext, this.mediaTypes); - } - else { - strategy = new PathExtensionContentNegotiationStrategy(this.mediaTypes); - } - strategy.setIgnoreUnknownExtensions(this.ignoreUnknownPathExtensions); - if (this.useRegisteredExtensionsOnly != null) { - strategy.setUseRegisteredExtensionsOnly(this.useRegisteredExtensionsOnly); - } - strategies.add(strategy); - } if (this.favorParameter) { ParameterContentNegotiationStrategy strategy = new ParameterContentNegotiationStrategy(this.mediaTypes); strategy.setParameterName(this.parameterName); @@ -367,7 +276,7 @@ public class ContentNegotiationManagerFactoryBean // Ensure media type mappings are available via ContentNegotiationManager#getMediaTypeMappings() // independent of path extension or parameter strategies. - if (!CollectionUtils.isEmpty(this.mediaTypes) && !this.favorPathExtension && !this.favorParameter) { + if (!CollectionUtils.isEmpty(this.mediaTypes) && !this.favorParameter) { this.contentNegotiationManager.addFileExtensionResolvers( new MappingMediaTypeFileExtensionResolver(this.mediaTypes)); } @@ -387,9 +296,4 @@ public class ContentNegotiationManagerFactoryBean return ContentNegotiationManager.class; } - @Override - public boolean isSingleton() { - return true; - } - } diff --git a/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java deleted file mode 100644 index 8740f5c34aa..00000000000 --- a/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright 2002-2024 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.accept; - -import java.util.Locale; -import java.util.Map; - -import jakarta.servlet.http.HttpServletRequest; - -import org.springframework.core.io.Resource; -import org.springframework.http.MediaType; -import org.springframework.http.MediaTypeFactory; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.util.UriUtils; -import org.springframework.web.util.UrlPathHelper; - -/** - * A {@code ContentNegotiationStrategy} that resolves the file extension in the - * request path to a key to be used to look up a media type. - * - *

If the file extension is not found in the explicit registrations provided - * to the constructor, the {@link MediaTypeFactory} is used as a fallback - * mechanism. - * - * @author Rossen Stoyanchev - * @since 3.2 - * @deprecated as of 5.2.4. See class-level note in - * {@link ContentNegotiationManagerFactoryBean} on the deprecation of path - * extension config options. - */ -@Deprecated -public class PathExtensionContentNegotiationStrategy extends AbstractMappingContentNegotiationStrategy { - - private UrlPathHelper urlPathHelper = new UrlPathHelper(); - - - /** - * Create an instance without any mappings to start with. Mappings may be added - * later on if any extensions are resolved through the Java Activation framework. - */ - public PathExtensionContentNegotiationStrategy() { - this(null); - } - - /** - * Create an instance with the given map of file extensions and media types. - */ - public PathExtensionContentNegotiationStrategy(@Nullable Map mediaTypes) { - super(mediaTypes); - setUseRegisteredExtensionsOnly(false); - setIgnoreUnknownExtensions(true); - this.urlPathHelper.setUrlDecode(false); - } - - - /** - * Configure a {@code UrlPathHelper} to use in {@link #getMediaTypeKey} - * in order to derive the lookup path for a target request URL path. - * @since 4.2.8 - */ - public void setUrlPathHelper(UrlPathHelper urlPathHelper) { - this.urlPathHelper = urlPathHelper; - } - - /** - * Indicate whether to use the Java Activation Framework as a fallback option - * to map from file extensions to media types. - * @deprecated as of 5.0, in favor of {@link #setUseRegisteredExtensionsOnly(boolean)}. - */ - @Deprecated - public void setUseJaf(boolean useJaf) { - setUseRegisteredExtensionsOnly(!useJaf); - } - - @Override - @Nullable - protected String getMediaTypeKey(NativeWebRequest webRequest) { - HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); - if (request == null) { - return null; - } - // Ignore LOOKUP_PATH attribute, use our own "fixed" UrlPathHelper with decoding off - String path = this.urlPathHelper.getLookupPathForRequest(request); - String extension = UriUtils.extractFileExtension(path); - return (StringUtils.hasText(extension) ? extension.toLowerCase(Locale.ROOT) : null); - } - - /** - * A public method exposing the knowledge of the path extension strategy to - * resolve file extensions to a {@link MediaType} in this case for a given - * {@link Resource}. The method first looks up any explicitly registered - * file extensions first and then falls back on {@link MediaTypeFactory} if available. - * @param resource the resource to look up - * @return the MediaType for the extension, or {@code null} if none found - * @since 4.3 - */ - @Nullable - public MediaType getMediaTypeForResource(Resource resource) { - Assert.notNull(resource, "Resource must not be null"); - MediaType mediaType = null; - String filename = resource.getFilename(); - String extension = StringUtils.getFilenameExtension(filename); - if (extension != null) { - mediaType = lookupMediaType(extension); - } - if (mediaType == null) { - mediaType = MediaTypeFactory.getMediaType(filename).orElse(null); - } - return mediaType; - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java deleted file mode 100644 index fee82413c17..00000000000 --- a/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2002-2020 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.accept; - -import java.util.Map; - -import jakarta.servlet.ServletContext; - -import org.springframework.core.io.Resource; -import org.springframework.http.MediaType; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.web.HttpMediaTypeNotAcceptableException; -import org.springframework.web.context.request.NativeWebRequest; - -/** - * Extends {@code PathExtensionContentNegotiationStrategy} that also uses - * {@link ServletContext#getMimeType(String)} to resolve file extensions. - * - * @author Rossen Stoyanchev - * @since 3.2 - * @deprecated as of 5.2.4. See class-level note in - * {@link ContentNegotiationManagerFactoryBean} on the deprecation of path - * extension config options. - */ -@Deprecated -public class ServletPathExtensionContentNegotiationStrategy extends PathExtensionContentNegotiationStrategy { - - private final ServletContext servletContext; - - - /** - * Create an instance without any mappings to start with. Mappings may be - * added later when extensions are resolved through - * {@link ServletContext#getMimeType(String)} or via - * {@link org.springframework.http.MediaTypeFactory}. - */ - public ServletPathExtensionContentNegotiationStrategy(ServletContext context) { - this(context, null); - } - - /** - * Create an instance with the given extension-to-MediaType lookup. - */ - public ServletPathExtensionContentNegotiationStrategy( - ServletContext servletContext, @Nullable Map mediaTypes) { - - super(mediaTypes); - Assert.notNull(servletContext, "ServletContext is required"); - this.servletContext = servletContext; - } - - - /** - * Resolve file extension via {@link ServletContext#getMimeType(String)} - * and also delegate to base class for a potential - * {@link org.springframework.http.MediaTypeFactory} lookup. - */ - @Override - @Nullable - protected MediaType handleNoMatch(NativeWebRequest webRequest, String extension) - throws HttpMediaTypeNotAcceptableException { - - MediaType mediaType = null; - String mimeType = this.servletContext.getMimeType("file." + extension); - if (StringUtils.hasText(mimeType)) { - mediaType = MediaType.parseMediaType(mimeType); - } - if (mediaType == null || MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) { - MediaType superMediaType = super.handleNoMatch(webRequest, extension); - if (superMediaType != null) { - mediaType = superMediaType; - } - } - return mediaType; - } - - /** - * Extends the base class - * {@link PathExtensionContentNegotiationStrategy#getMediaTypeForResource} - * with the ability to also look up through the ServletContext. - * @param resource the resource to look up - * @return the MediaType for the extension, or {@code null} if none found - * @since 4.3 - */ - @Override - @Nullable - public MediaType getMediaTypeForResource(Resource resource) { - MediaType mediaType = null; - String mimeType = this.servletContext.getMimeType(resource.getFilename()); - if (StringUtils.hasText(mimeType)) { - mediaType = MediaType.parseMediaType(mimeType); - } - if (mediaType == null || MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) { - MediaType superMediaType = super.getMediaTypeForResource(resource); - if (superMediaType != null) { - mediaType = superMediaType; - } - } - return mediaType; - } - -} diff --git a/spring-web/src/main/java/org/springframework/web/accept/package-info.java b/spring-web/src/main/java/org/springframework/web/accept/package-info.java index 928dca73b77..967fe7aadd5 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/package-info.java +++ b/spring-web/src/main/java/org/springframework/web/accept/package-info.java @@ -3,8 +3,7 @@ * *

{@link org.springframework.web.accept.ContentNegotiationStrategy} is the main * abstraction for determining requested {@linkplain org.springframework.http.MediaType media types} - * with implementations based on - * {@linkplain org.springframework.web.accept.PathExtensionContentNegotiationStrategy path extensions}, a + * with implementations based on a * {@linkplain org.springframework.web.accept.ParameterContentNegotiationStrategy a request parameter}, the * {@linkplain org.springframework.web.accept.HeaderContentNegotiationStrategy 'Accept' header}, or a * {@linkplain org.springframework.web.accept.FixedContentNegotiationStrategy default content type}. 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 e854fea7505..f84cf56b480 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-2023 the original author or authors. + * Copyright 2002-2024 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. @@ -60,7 +60,6 @@ class ContentNegotiationManagerFactoryBeanTests { this.webRequest = new ServletWebRequest(this.servletRequest); this.factoryBean = new ContentNegotiationManagerFactoryBean(); - this.factoryBean.setServletContext(this.servletRequest.getServletContext()); } @@ -115,42 +114,6 @@ class ContentNegotiationManagerFactoryBeanTests { } - @Test - @SuppressWarnings("deprecation") - void favorPath() throws Exception { - this.factoryBean.setFavorPathExtension(true); - this.factoryBean.addMediaType("bar", new MediaType("application", "bar")); - this.factoryBean.afterPropertiesSet(); - ContentNegotiationManager manager = this.factoryBean.getObject(); - - this.servletRequest.setRequestURI("/flower.foo"); - assertThat(manager.resolveMediaTypes(this.webRequest)) - .isEqualTo(Collections.singletonList(new MediaType("application", "foo"))); - - this.servletRequest.setRequestURI("/flower.bar"); - assertThat(manager.resolveMediaTypes(this.webRequest)) - .isEqualTo(Collections.singletonList(new MediaType("application", "bar"))); - - this.servletRequest.setRequestURI("/flower.gif"); - assertThat(manager.resolveMediaTypes(this.webRequest)) - .isEqualTo(Collections.singletonList(MediaType.IMAGE_GIF)); - } - - @Test // SPR-10170 - @SuppressWarnings("deprecation") - void favorPathWithIgnoreUnknownPathExtensionTurnedOff() { - this.factoryBean.setFavorPathExtension(true); - this.factoryBean.setIgnoreUnknownPathExtensions(false); - this.factoryBean.afterPropertiesSet(); - ContentNegotiationManager manager = this.factoryBean.getObject(); - - this.servletRequest.setRequestURI("/flower.foobarbaz"); - this.servletRequest.addParameter("format", "json"); - - assertThatExceptionOfType(HttpMediaTypeNotAcceptableException.class).isThrownBy(() -> - manager.resolveMediaTypes(this.webRequest)); - } - @Test void favorParameter() throws Exception { this.factoryBean.setFavorParameter(true); @@ -180,9 +143,7 @@ class ContentNegotiationManagerFactoryBeanTests { } @Test - @SuppressWarnings("deprecation") void mediaTypeMappingsWithoutPathAndParameterStrategies() { - this.factoryBean.setFavorPathExtension(false); this.factoryBean.setFavorParameter(false); Properties properties = new Properties(); @@ -201,9 +162,7 @@ class ContentNegotiationManagerFactoryBeanTests { } @Test - @SuppressWarnings("deprecation") void fileExtensions() { - this.factoryBean.setFavorPathExtension(false); this.factoryBean.setFavorParameter(false); Properties properties = new Properties(); 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 deleted file mode 100644 index c1adc00d76d..00000000000 --- a/spring-web/src/test/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategyTests.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2002-2024 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. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.accept; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.junit.jupiter.api.Test; - -import org.springframework.http.MediaType; -import org.springframework.web.HttpMediaTypeNotAcceptableException; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.context.request.ServletWebRequest; -import org.springframework.web.testfixture.servlet.MockHttpServletRequest; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatExceptionOfType; - -/** - * A test fixture for {@link PathExtensionContentNegotiationStrategy}. - * - * @author Rossen Stoyanchev - * @since 3.2 - */ -@SuppressWarnings("deprecation") -class PathExtensionContentNegotiationStrategyTests { - - private final MockHttpServletRequest servletRequest = new MockHttpServletRequest(); - - private final NativeWebRequest webRequest = new ServletWebRequest(servletRequest); - - private PathExtensionContentNegotiationStrategy strategy = new PathExtensionContentNegotiationStrategy(); - - - @Test - void resolveMediaTypesFromMapping() throws Exception { - this.servletRequest.setRequestURI("test.html"); - - List mediaTypes = this.strategy.resolveMediaTypes(this.webRequest); - - assertThat(mediaTypes).containsExactly(new MediaType("text", "html")); - - Map mapping = Collections.singletonMap("HTML", MediaType.APPLICATION_XHTML_XML); - this.strategy = new PathExtensionContentNegotiationStrategy(mapping); - mediaTypes = this.strategy.resolveMediaTypes(this.webRequest); - - assertThat(mediaTypes).containsExactly(new MediaType("application", "xhtml+xml")); - } - - @Test - void resolveMediaTypesFromMediaTypeFactory() throws Exception { - this.servletRequest.setRequestURI("test.xls"); - - List mediaTypes = this.strategy.resolveMediaTypes(this.webRequest); - - assertThat(mediaTypes).containsExactly(new MediaType("application", "vnd.ms-excel")); - } - - @Test // SPR-8678 - void getMediaTypeFilenameWithContextPath() throws Exception { - this.servletRequest.setContextPath("/project-1.0.0.M3"); - this.servletRequest.setRequestURI("/project-1.0.0.M3/"); - assertThat(this.strategy.resolveMediaTypes(webRequest)).as("Context path should be excluded").isEqualTo(ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST); - - this.servletRequest.setRequestURI("/project-1.0.0.M3"); - assertThat(this.strategy.resolveMediaTypes(webRequest)).as("Context path should be excluded").isEqualTo(ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST); - } - - @Test // SPR-9390 - void getMediaTypeFilenameWithEncodedURI() throws Exception { - this.servletRequest.setRequestURI("/quo%20vadis%3f.html"); - List result = this.strategy.resolveMediaTypes(webRequest); - - assertThat(result).as("Invalid content type").isEqualTo(Collections.singletonList(new MediaType("text", "html"))); - } - - @Test // SPR-10170 - void resolveMediaTypesIgnoreUnknownExtension() throws Exception { - this.servletRequest.setRequestURI("test.foobar"); - - List mediaTypes = this.strategy.resolveMediaTypes(this.webRequest); - - assertThat(mediaTypes).isEqualTo(ContentNegotiationStrategy.MEDIA_TYPE_ALL_LIST); - } - - @Test - void resolveMediaTypesDoNotIgnoreUnknownExtension() { - this.servletRequest.setRequestURI("test.foobar"); - - this.strategy.setIgnoreUnknownExtensions(false); - assertThatExceptionOfType(HttpMediaTypeNotAcceptableException.class) - .isThrownBy(() -> this.strategy.resolveMediaTypes(this.webRequest)); - } - -} diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceWebHandlerTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceWebHandlerTests.java index 04bf4ec91a7..c6574131ee1 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceWebHandlerTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/resource/ResourceWebHandlerTests.java @@ -176,8 +176,7 @@ class ResourceWebHandlerTests { assertResponseBody(exchange, "foo bar foo bar foo bar"); } - @Test - // SPR-14577 + @Test // SPR-14577 void getMediaTypeWithFavorPathExtensionOff() throws Exception { List paths = List.of(new ClassPathResource("test/", getClass())); ResourceWebHandler handler = new ResourceWebHandler(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java index 4900b12678f..8828c103e37 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java @@ -188,11 +188,6 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser { parseResourceChain(resourceHandlerDef, context, resourceChainElement, source); } - Object manager = MvcNamespaceUtils.getContentNegotiationManager(context); - if (manager != null) { - values.add("contentNegotiationManager", manager); - } - String beanName = context.getReaderContext().generateBeanName(resourceHandlerDef); context.getRegistry().registerBeanDefinition(beanName, resourceHandlerDef); context.registerComponent(new BeanComponentDefinition(resourceHandlerDef, beanName)); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer.java index 7e4d475aa8c..a13d9855acd 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiationConfigurer.java @@ -55,13 +55,6 @@ import org.springframework.web.accept.ParameterContentNegotiationStrategy; * Off * * - * {@link #favorPathExtension} - * false (as of 5.3) - * {@link org.springframework.web.accept.PathExtensionContentNegotiationStrategy - * PathExtensionContentNegotiationStrategy} - * Off - * - * * {@link #ignoreAcceptHeader} * false * {@link HeaderContentNegotiationStrategy} @@ -84,13 +77,6 @@ import org.springframework.web.accept.ParameterContentNegotiationStrategy; *

As of 5.0 you can set the exact strategies to use via * {@link #strategies(List)}. * - *

Note: if you must use URL-based content type resolution, - * the use of a query parameter is simpler and preferable to the use of a path - * extension since the latter can cause issues with URI variables, path - * parameters, and URI decoding. Consider setting {@link #favorPathExtension} - * to {@literal false} or otherwise set the strategies to use explicitly via - * {@link #strategies(List)}. - * * @author Rossen Stoyanchev * @since 3.2 */ @@ -101,16 +87,6 @@ public class ContentNegotiationConfigurer { private final Map mediaTypes = new HashMap<>(); - /** - * Class constructor with {@link jakarta.servlet.ServletContext}. - */ - public ContentNegotiationConfigurer(@Nullable ServletContext servletContext) { - if (servletContext != null) { - this.factory.setServletContext(servletContext); - } - } - - /** * Set the exact list of strategies to use. *

Note: use of this method is mutually exclusive with @@ -144,20 +120,6 @@ public class ContentNegotiationConfigurer { return this; } - /** - * Whether the path extension in the URL path should be used to determine - * the requested media type. - *

By default this is set to {@code false} in which case path extensions - * have no impact on content negotiation. - * @deprecated as of 5.2.4. See deprecation note on - * {@link ContentNegotiationManagerFactoryBean#setFavorPathExtension(boolean)}. - */ - @Deprecated - public ContentNegotiationConfigurer favorPathExtension(boolean favorPathExtension) { - this.factory.setFavorPathExtension(favorPathExtension); - return this; - } - /** * Add a mapping from a key, extracted from a path extension or a query * parameter, to a MediaType. This is required in order for the parameter @@ -202,37 +164,11 @@ public class ContentNegotiationConfigurer { } /** - * Whether to ignore requests with path extension that cannot be resolved - * to any media type. Setting this to {@code false} will result in an - * {@code HttpMediaTypeNotAcceptableException} if there is no match. - *

By default this is set to {@code true}. - * @deprecated as of 5.2.4. See deprecation note on - * {@link ContentNegotiationManagerFactoryBean#setIgnoreUnknownPathExtensions(boolean)}. - */ - @Deprecated - public ContentNegotiationConfigurer ignoreUnknownPathExtensions(boolean ignore) { - this.factory.setIgnoreUnknownPathExtensions(ignore); - return this; - } - - /** - * When {@link #favorPathExtension} is set, this property determines whether - * to allow use of JAF (Java Activation Framework) to resolve a path - * extension to a specific MediaType. - * @deprecated as of 5.0, in favor of {@link #useRegisteredExtensionsOnly(boolean)} - * which has reverse behavior - */ - @Deprecated - public ContentNegotiationConfigurer useJaf(boolean useJaf) { - return this.useRegisteredExtensionsOnly(!useJaf); - } - - /** - * When {@link #favorPathExtension favorPathExtension} is set, this + * When {@link #favorParameter(boolean)} is set, this * property determines whether to use only registered {@code MediaType} mappings * to resolve a path extension to a specific MediaType. - *

By default this is not set in which case - * {@code PathExtensionContentNegotiationStrategy} will use defaults if available. + *

By default, this is not set in which case + * {@code ParameterContentNegotiationStrategy} will use defaults if available. */ public ContentNegotiationConfigurer useRegisteredExtensionsOnly(boolean useRegisteredExtensionsOnly) { this.factory.setUseRegisteredExtensionsOnly(useRegisteredExtensionsOnly); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.java index 43b63a3b6aa..99e132ab1ad 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2021 the original author or authors. + * Copyright 2002-2024 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. @@ -66,9 +66,6 @@ public class ResourceHandlerRegistry { private final ApplicationContext applicationContext; - @Nullable - private final ContentNegotiationManager contentNegotiationManager; - @Nullable private final UrlPathHelper pathHelper; @@ -111,7 +108,6 @@ public class ResourceHandlerRegistry { Assert.notNull(applicationContext, "ApplicationContext is required"); this.applicationContext = applicationContext; this.servletContext = servletContext; - this.contentNegotiationManager = contentNegotiationManager; this.pathHelper = pathHelper; } @@ -173,15 +169,11 @@ public class ResourceHandlerRegistry { return new SimpleUrlHandlerMapping(urlMap, this.order); } - @SuppressWarnings("deprecation") private ResourceHttpRequestHandler getRequestHandler(ResourceHandlerRegistration registration) { ResourceHttpRequestHandler handler = registration.getRequestHandler(); if (this.pathHelper != null) { handler.setUrlPathHelper(this.pathHelper); } - if (this.contentNegotiationManager != null) { - handler.setContentNegotiationManager(this.contentNegotiationManager); - } handler.setServletContext(this.servletContext); handler.setApplicationContext(this.applicationContext); try { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java index e4f232e2ce0..4b3e18e1ec0 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java @@ -430,7 +430,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv @Bean public ContentNegotiationManager mvcContentNegotiationManager() { if (this.contentNegotiationManager == null) { - ContentNegotiationConfigurer configurer = new ContentNegotiationConfigurer(this.servletContext); + ContentNegotiationConfigurer configurer = new ContentNegotiationConfigurer(); configurer.mediaTypes(getDefaultMediaTypes()); configureContentNegotiation(configurer); this.contentNegotiationManager = configurer.buildContentNegotiationManager(); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java index 14cd680e4d9..aa38801ed94 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandler.java @@ -280,31 +280,6 @@ public class ResourceHttpRequestHandler extends WebContentGenerator return this.resourceRegionHttpMessageConverter; } - /** - * Configure a {@code ContentNegotiationManager} to help determine the - * media types for resources being served. If the manager contains a path - * extension strategy it will be checked for registered file extension. - * @since 4.3 - * @deprecated as of 5.2.4 in favor of using {@link #setMediaTypes(Map)} - * with mappings possibly obtained from - * {@link ContentNegotiationManager#getMediaTypeMappings()}. - */ - @Deprecated - public void setContentNegotiationManager(@Nullable ContentNegotiationManager contentNegotiationManager) { - this.contentNegotiationManager = contentNegotiationManager; - } - - /** - * Return the configured content negotiation manager. - * @since 4.3 - * @deprecated as of 5.2.4 - */ - @Nullable - @Deprecated - public ContentNegotiationManager getContentNegotiationManager() { - return this.contentNegotiationManager; - } - /** * Add mappings between file extensions, extracted from the filename of a * static {@link Resource}, and corresponding media type to set on the @@ -459,18 +434,6 @@ public class ResourceHttpRequestHandler extends WebContentGenerator if (this.resourceRegionHttpMessageConverter == null) { this.resourceRegionHttpMessageConverter = new ResourceRegionHttpMessageConverter(); } - - ContentNegotiationManager manager = getContentNegotiationManager(); - if (manager != null) { - setMediaTypes(manager.getMediaTypeMappings()); - } - - @SuppressWarnings("deprecation") - org.springframework.web.accept.PathExtensionContentNegotiationStrategy strategy = - initContentNegotiationStrategy(); - if (strategy != null) { - setMediaTypes(strategy.getMediaTypes()); - } } private void resolveResourceLocations() { @@ -546,21 +509,6 @@ public class ResourceHttpRequestHandler extends WebContentGenerator } } - /** - * Initialize the strategy to use to determine the media type for a resource. - * @deprecated as of 5.2.4 this method returns {@code null}, and if a - * subclass returns an actual instance, the instance is used only as a - * source of media type mappings, if it contains any. Please, use - * {@link #setMediaTypes(Map)} instead, or if you need to change behavior, - * you can override {@link #getMediaType(HttpServletRequest, Resource)}. - */ - @Nullable - @Deprecated - @SuppressWarnings("deprecation") - protected org.springframework.web.accept.PathExtensionContentNegotiationStrategy initContentNegotiationStrategy() { - return null; - } - /** * Processes a resource 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 bd3b215287a..a847f152bee 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-2023 the original author or authors. + * Copyright 2002-2024 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. @@ -205,7 +205,6 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport } AnnotationAwareOrderComparator.sort(this.viewResolvers); - this.cnmFactoryBean.setServletContext(servletContext); } @Override diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java index da670cb0ac9..a77c77befc7 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java @@ -380,7 +380,6 @@ public class MvcNamespaceTests { } @Test - @SuppressWarnings("deprecation") void testResources() throws Exception { loadBeanDefinitions("mvc-config-resources.xml"); @@ -390,10 +389,6 @@ public class MvcNamespaceTests { RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class); ContentNegotiationManager manager = mapping.getContentNegotiationManager(); - ResourceHttpRequestHandler handler = appContext.getBean(ResourceHttpRequestHandler.class); - assertThat(handler).isNotNull(); - assertThat(handler.getContentNegotiationManager()).isSameAs(manager); - SimpleUrlHandlerMapping resourceMapping = appContext.getBean(SimpleUrlHandlerMapping.class); assertThat(resourceMapping).isNotNull(); assertThat(resourceMapping.getOrder()).isEqualTo(Ordered.LOWEST_PRECEDENCE - 1); 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 3a6a1686d47..4628c64e016 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 @@ -49,7 +49,7 @@ class ContentNegotiationConfigurerTests { void setup() { this.servletRequest = new MockHttpServletRequest(); this.webRequest = new ServletWebRequest(this.servletRequest); - this.configurer = new ContentNegotiationConfigurer(this.servletRequest.getServletContext()); + this.configurer = new ContentNegotiationConfigurer(); } diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportExtensionTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportExtensionTests.java index 6c3f801fb85..d311a5e0810 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportExtensionTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportExtensionTests.java @@ -75,7 +75,6 @@ import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionRes import org.springframework.web.servlet.mvc.method.RequestMappingInfo; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; -import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; import org.springframework.web.servlet.resource.ResourceUrlProviderExposingInterceptor; import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; import org.springframework.web.servlet.view.InternalResourceViewResolver; @@ -264,7 +263,6 @@ class WebMvcConfigurationSupportExtensionTests { } @Test - @SuppressWarnings("deprecation") public void contentNegotiation() throws Exception { MockHttpServletRequest request = new MockHttpServletRequest("GET", "/foo"); NativeWebRequest webRequest = new ServletWebRequest(request); @@ -287,11 +285,7 @@ class WebMvcConfigurationSupportExtensionTests { request = new MockHttpServletRequest("GET", "/resources/foo.gif"); HandlerExecutionChain chain = handlerMapping.getHandler(request); - assertThat(chain).isNotNull(); - ResourceHttpRequestHandler handler = (ResourceHttpRequestHandler) chain.getHandler(); - assertThat(handler).isNotNull(); - assertThat(handler.getContentNegotiationManager()).isSameAs(manager); } @Test diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java index c4b1f4de5db..d796b37a4fc 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/ResourceHttpRequestHandlerTests.java @@ -18,6 +18,7 @@ package org.springframework.web.servlet.resource; import java.io.IOException; import java.util.List; +import java.util.Map; import jakarta.servlet.http.HttpServletResponse; import org.junit.jupiter.api.BeforeEach; @@ -33,8 +34,6 @@ import org.springframework.http.HttpMethod; import org.springframework.http.MediaType; import org.springframework.util.StringUtils; import org.springframework.web.HttpRequestMethodNotSupportedException; -import org.springframework.web.accept.ContentNegotiationManager; -import org.springframework.web.accept.ContentNegotiationManagerFactoryBean; import org.springframework.web.context.support.StaticWebApplicationContext; import org.springframework.web.servlet.HandlerMapping; import org.springframework.web.testfixture.servlet.MockHttpServletRequest; @@ -127,18 +126,12 @@ class ResourceHttpRequestHandlerTests { } @Test // SPR-13658 - @SuppressWarnings("deprecation") void getResourceWithRegisteredMediaType() throws Exception { - ContentNegotiationManagerFactoryBean factory = new ContentNegotiationManagerFactoryBean(); - factory.addMediaType("bar", new MediaType("foo", "bar")); - factory.afterPropertiesSet(); - ContentNegotiationManager manager = factory.getObject(); - List paths = List.of(new ClassPathResource("test/", getClass())); ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler(); handler.setServletContext(new MockServletContext()); + handler.setMediaTypes(Map.of("bar", new MediaType("foo", "bar"))); handler.setLocations(paths); - handler.setContentNegotiationManager(manager); handler.afterPropertiesSet(); this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.bar"); @@ -148,17 +141,12 @@ class ResourceHttpRequestHandlerTests { assertThat(this.response.getContentAsString()).isEqualTo("h1 { color:red; }"); } - @Test // SPR-14577 + @Test // SPR-14577 void getMediaTypeWithFavorPathExtensionOff() throws Exception { - ContentNegotiationManagerFactoryBean factory = new ContentNegotiationManagerFactoryBean(); - factory.afterPropertiesSet(); - ContentNegotiationManager manager = factory.getObject(); - List paths = List.of(new ClassPathResource("test/", getClass())); ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler(); handler.setServletContext(new MockServletContext()); handler.setLocations(paths); - handler.setContentNegotiationManager(manager); handler.afterPropertiesSet(); this.request.addHeader("Accept", "application/json,text/plain,*/*"); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolverTests.java index 1a0d584b1d9..3da00b5f214 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolverTests.java @@ -84,7 +84,7 @@ class ContentNegotiatingViewResolverTests { } @Test - void resolveViewNameWithPathExtension() throws Exception { + void resolveViewNameWithExtensionByParameter() throws Exception { request.setRequestURI("/test"); request.setParameter("format", "xls"); @@ -310,77 +310,6 @@ class ContentNegotiatingViewResolverTests { assertThat(result).as("Invalid view").isSameAs(viewMock3); } - @Test - @SuppressWarnings("deprecation") - public void resolveViewNameFilename() throws Exception { - request.setRequestURI("/test.html"); - - ContentNegotiationManager manager = - new ContentNegotiationManager(new org.springframework.web.accept.PathExtensionContentNegotiationStrategy()); - - ViewResolver viewResolverMock1 = mock(ViewResolver.class, "viewResolver1"); - ViewResolver viewResolverMock2 = mock(ViewResolver.class, "viewResolver2"); - viewResolver.setContentNegotiationManager(manager); - viewResolver.setViewResolvers(Arrays.asList(viewResolverMock1, viewResolverMock2)); - - viewResolver.afterPropertiesSet(); - - View viewMock1 = mock(View.class, "application_xml"); - View viewMock2 = mock(View.class, "text_html"); - - String viewName = "view"; - Locale locale = Locale.ENGLISH; - - given(viewResolverMock1.resolveViewName(viewName, locale)).willReturn(viewMock1); - given(viewResolverMock1.resolveViewName(viewName + ".html", locale)).willReturn(null); - given(viewResolverMock2.resolveViewName(viewName, locale)).willReturn(null); - given(viewResolverMock2.resolveViewName(viewName + ".html", locale)).willReturn(viewMock2); - given(viewMock1.getContentType()).willReturn("application/xml"); - given(viewMock2.getContentType()).willReturn("text/html;charset=ISO-8859-1"); - - View result = viewResolver.resolveViewName(viewName, locale); - assertThat(result).as("Invalid view").isSameAs(viewMock2); - } - - @Test - @SuppressWarnings("deprecation") - public void resolveViewNameFilenameDefaultView() throws Exception { - request.setRequestURI("/test.json"); - - Map mapping = Collections.singletonMap("json", MediaType.APPLICATION_JSON); - org.springframework.web.accept.PathExtensionContentNegotiationStrategy pathStrategy = - new org.springframework.web.accept.PathExtensionContentNegotiationStrategy(mapping); - viewResolver.setContentNegotiationManager(new ContentNegotiationManager(pathStrategy)); - - ViewResolver viewResolverMock1 = mock(); - ViewResolver viewResolverMock2 = mock(); - viewResolver.setViewResolvers(Arrays.asList(viewResolverMock1, viewResolverMock2)); - - View viewMock1 = mock(View.class, "application_xml"); - View viewMock2 = mock(View.class, "text_html"); - View viewMock3 = mock(View.class, "application_json"); - - List defaultViews = new ArrayList<>(); - defaultViews.add(viewMock3); - viewResolver.setDefaultViews(defaultViews); - - viewResolver.afterPropertiesSet(); - - String viewName = "view"; - Locale locale = Locale.ENGLISH; - - given(viewResolverMock1.resolveViewName(viewName, locale)).willReturn(viewMock1); - given(viewResolverMock1.resolveViewName(viewName + ".json", locale)).willReturn(null); - given(viewResolverMock2.resolveViewName(viewName, locale)).willReturn(viewMock2); - given(viewResolverMock2.resolveViewName(viewName + ".json", locale)).willReturn(null); - given(viewMock1.getContentType()).willReturn("application/xml"); - given(viewMock2.getContentType()).willReturn("text/html;charset=ISO-8859-1"); - given(viewMock3.getContentType()).willReturn("application/json"); - - View result = viewResolver.resolveViewName(viewName, locale); - assertThat(result).as("Invalid view").isSameAs(viewMock3); - } - @Test void resolveViewContentTypeNull() throws Exception { request.addHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");