Introduce 'useRegisteredExtensionsOnly' property in classes using MediaTypeFactory

This commit introduces a `useRegisteredExtensionsOnly` property that
indicates whether classes that use the `MediaTypeFactory` for supplying
default media types can do so.

 - In classes that were introduced in Spring 5.0, the
 `useRegisteredExtensionsOnly` property takes the place of the
 `useJaf` property that was removed in 0aaa652
 - In classes that existed before Spring 5.0, the
 `useRegisteredExtensionsOnly` property is added in addition to the
 deprecated `useJaf`, the latter delegating to the former, but with
 flipped behavior.

Issue: SPR-14908
This commit is contained in:
Arjen Poutsma
2017-03-23 14:56:43 +01:00
parent e2aa880301
commit a287e67992
8 changed files with 101 additions and 22 deletions

View File

@@ -104,11 +104,9 @@ public class MediaTypeFactory {
* @return the corresponding media type, or {@code null} if none found
*/
public static Optional<MediaType> getMediaType(Resource resource) {
if (resource == null) {
return Optional.empty();
}
String filename = resource.getFilename();
return (filename != null ? getMediaType(filename) : Optional.empty());
return Optional.ofNullable(resource)
.map(Resource::getFilename)
.flatMap(MediaTypeFactory::getMediaType);
}
/**
@@ -117,8 +115,7 @@ public class MediaTypeFactory {
* @return the corresponding media type, or {@code null} if none found
*/
public static Optional<MediaType> getMediaType(String filename) {
List<MediaType> mediaTypes = getMediaTypes(filename);
return (!mediaTypes.isEmpty() ? Optional.of(mediaTypes.get(0)) : Optional.empty());
return getMediaTypes(filename).stream().findFirst();
}
/**

View File

@@ -143,7 +143,9 @@ public class ContentNegotiationManager implements ContentNegotiationStrategy, Me
* <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, the list of extensions may
* "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.
*/

View File

@@ -100,6 +100,8 @@ public class ContentNegotiationManagerFactoryBean
private boolean ignoreUnknownPathExtensions = true;
private Boolean useRegisteredExtensionsOnly;
private String parameterName = "format";
private ContentNegotiationStrategy defaultNegotiationStrategy;
@@ -175,10 +177,27 @@ public class ContentNegotiationManagerFactoryBean
}
/**
* @deprecated as 5.0, in favor of {@link MediaTypeFactory}, which has no JAF dependency.
* @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} is set, this
* property determines whether to use only registered {@code MediaType} mappings
* to resolve a path extension to a specific MediaType.
* <p>By default this is not set in which case
* {@code PathExtensionContentNegotiationStrategy} will use defaults if available.
*/
public void setUseRegisteredExtensionsOnly(boolean useRegisteredExtensionsOnly) {
this.useRegisteredExtensionsOnly = useRegisteredExtensionsOnly;
}
private boolean useRegisteredExtensionsOnly() {
return (this.useRegisteredExtensionsOnly != null && this.useRegisteredExtensionsOnly);
}
/**
@@ -244,7 +263,7 @@ public class ContentNegotiationManagerFactoryBean
if (this.favorPathExtension) {
PathExtensionContentNegotiationStrategy strategy;
if (this.servletContext != null) {
if (this.servletContext != null && !useRegisteredExtensionsOnly()) {
strategy = new ServletPathExtensionContentNegotiationStrategy(
this.servletContext, this.mediaTypes);
}
@@ -252,6 +271,9 @@ public class ContentNegotiationManagerFactoryBean
strategy = new PathExtensionContentNegotiationStrategy(this.mediaTypes);
}
strategy.setIgnoreUnknownExtensions(this.ignoreUnknownPathExtensions);
if (this.useRegisteredExtensionsOnly != null) {
strategy.setUseRegisteredExtensionsOnly(this.useRegisteredExtensionsOnly);
}
strategies.add(strategy);
}

View File

@@ -51,6 +51,8 @@ public class PathExtensionContentNegotiationStrategy extends AbstractMappingCont
private UrlPathHelper urlPathHelper = new UrlPathHelper();
private boolean useRegisteredExtensionsOnly = false;
private boolean ignoreUnknownExtensions = true;
@@ -81,10 +83,20 @@ public class PathExtensionContentNegotiationStrategy extends AbstractMappingCont
}
/**
* @deprecated as 5.0, in favor of {@link MediaTypeFactory}, which has no JAF dependency.
* @deprecated as of 5.0, in favor of {@link #setUseRegisteredExtensionsOnly(boolean)}.
*/
@Deprecated
public void setUseJaf(boolean useJaf) {
setUseRegisteredExtensionsOnly(!useJaf);
}
/**
* Whether to only use the registered mappings to look up file extensions, or also refer to
* defaults.
* <p>By default this is set to {@code false}, meaning that defaults are used.
*/
public void setUseRegisteredExtensionsOnly(boolean useRegisteredExtensionsOnly) {
this.useRegisteredExtensionsOnly = useRegisteredExtensionsOnly;
}
/**
@@ -113,9 +125,11 @@ public class PathExtensionContentNegotiationStrategy extends AbstractMappingCont
protected MediaType handleNoMatch(NativeWebRequest webRequest, String extension)
throws HttpMediaTypeNotAcceptableException {
Optional<MediaType> mediaType = MediaTypeFactory.getMediaType("file." + extension);
if (mediaType.isPresent()) {
return mediaType.get();
if (!this.useRegisteredExtensionsOnly) {
Optional<MediaType> mediaType = MediaTypeFactory.getMediaType("file." + extension);
if (mediaType.isPresent()) {
return mediaType.get();
}
}
if (this.ignoreUnknownExtensions) {
return null;

View File

@@ -93,6 +93,7 @@ public class ServletPathExtensionContentNegotiationStrategy extends PathExtensio
* @return the MediaType for the extension or {@code null}.
* @since 4.3
*/
@Override
public MediaType getMediaTypeForResource(Resource resource) {
MediaType mediaType = null;
if (this.servletContext != null) {