Remove Spring MVC path extension content negotiation
See gh-34036
This commit is contained in:
@@ -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}.
|
||||
* <p>By default this is set to {@literal false} but is overridden in
|
||||
* {@link PathExtensionContentNegotiationStrategy} to {@literal true}.
|
||||
* <p>By default, this is set to {@literal false}.
|
||||
*/
|
||||
public void setIgnoreUnknownExtensions(boolean ignoreUnknownExtensions) {
|
||||
this.ignoreUnknownExtensions = ignoreUnknownExtensions;
|
||||
|
||||
@@ -139,17 +139,6 @@ public class ContentNegotiationManager implements ContentNegotiationStrategy, Me
|
||||
return doResolveExtensions(resolver -> resolver.resolveFileExtensions(mediaType));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>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<String> getAllFileExtensions() {
|
||||
return doResolveExtensions(MediaTypeFileExtensionResolver::getAllFileExtensions);
|
||||
|
||||
@@ -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;
|
||||
* <td>Off</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #setFavorPathExtension favorPathExtension}</td>
|
||||
* <td>false (as of 5.3)</td>
|
||||
* <td>{@link PathExtensionContentNegotiationStrategy}</td>
|
||||
* <td>Off</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>{@link #setIgnoreAcceptHeader ignoreAcceptHeader}</td>
|
||||
* <td>false</td>
|
||||
* <td>{@link HeaderContentNegotiationStrategy}</td>
|
||||
@@ -85,20 +76,11 @@ import org.springframework.web.context.ServletContextAware;
|
||||
* methods and set the exact strategies to use via
|
||||
* {@link #setStrategies(List)}.
|
||||
*
|
||||
* <p><strong>Deprecation Note:</strong> 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
|
||||
* <a href="https://github.com/spring-projects/spring-framework/issues/24179">#24719</a>.
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Brian Clozel
|
||||
* @since 3.2
|
||||
*/
|
||||
public class ContentNegotiationManagerFactoryBean
|
||||
implements FactoryBean<ContentNegotiationManager>, ServletContextAware, InitializingBean {
|
||||
public class ContentNegotiationManagerFactoryBean implements FactoryBean<ContentNegotiationManager>, InitializingBean {
|
||||
|
||||
@Nullable
|
||||
private List<ContentNegotiationStrategy> strategies;
|
||||
@@ -108,12 +90,8 @@ public class ContentNegotiationManagerFactoryBean
|
||||
|
||||
private String parameterName = "format";
|
||||
|
||||
private boolean favorPathExtension = false;
|
||||
|
||||
private final Map<String, MediaType> 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.
|
||||
* <p>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.
|
||||
* <p>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.
|
||||
* <p><strong>Note:</strong> 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.
|
||||
* <p>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}.
|
||||
* <p>By default this is not set in which case dynamic resolution is on.
|
||||
* <p>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<ContentNegotiationStrategy> 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
* <p>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<String, MediaType> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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<String, MediaType> 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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -3,8 +3,7 @@
|
||||
*
|
||||
* <p>{@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}.
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<MediaType> mediaTypes = this.strategy.resolveMediaTypes(this.webRequest);
|
||||
|
||||
assertThat(mediaTypes).containsExactly(new MediaType("text", "html"));
|
||||
|
||||
Map<String, MediaType> 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<MediaType> 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<MediaType> 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<MediaType> 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));
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user