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 index 931d6ebe977..10d80b2bee4 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java +++ b/spring-web/src/main/java/org/springframework/web/accept/ServletPathExtensionContentNegotiationStrategy.java @@ -92,15 +92,18 @@ public class ServletPathExtensionContentNegotiationStrategy extends PathExtensio * @since 4.3 */ public MediaType getMediaTypeForResource(Resource resource) { - MediaType mediaType = super.getMediaTypeForResource(resource); - if (mediaType == null) { + MediaType mediaType = null; + if (this.servletContext != null) { String mimeType = this.servletContext.getMimeType(resource.getFilename()); if (StringUtils.hasText(mimeType)) { mediaType = MediaType.parseMediaType(mimeType); } } - if (MediaType.APPLICATION_OCTET_STREAM.equals(mediaType)) { - mediaType = null; + 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-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 e338e991d26..64ceea5ee95 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 @@ -20,6 +20,7 @@ import java.io.IOException; import java.net.URLDecoder; import java.util.ArrayList; import java.util.List; +import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; @@ -110,6 +111,8 @@ public class ResourceHttpRequestHandler extends WebContentGenerator private ContentNegotiationManager contentNegotiationManager; + private final ContentNegotiationManagerFactoryBean cnmFactoryBean = new ContentNegotiationManagerFactoryBean(); + private CorsConfiguration corsConfiguration; @@ -249,6 +252,11 @@ public class ResourceHttpRequestHandler extends WebContentGenerator return this.corsConfiguration; } + @Override + protected void initServletContext(ServletContext servletContext) { + this.cnmFactoryBean.setServletContext(servletContext); + } + @Override public void afterPropertiesSet() throws Exception { @@ -261,7 +269,8 @@ public class ResourceHttpRequestHandler extends WebContentGenerator } initAllowedLocations(); if (this.contentNegotiationManager == null) { - this.contentNegotiationManager = initContentNegotiationManager(); + this.cnmFactoryBean.afterPropertiesSet(); + this.contentNegotiationManager = this.cnmFactoryBean.getObject(); } if (this.resourceHttpMessageConverter == null) { this.resourceHttpMessageConverter = new ResourceHttpMessageConverter(); @@ -291,18 +300,6 @@ public class ResourceHttpRequestHandler extends WebContentGenerator } } - /** - * Create the {@code ContentNegotiationManager} to use to resolve the - * {@link MediaType} for requests. This implementation delegates to - * {@link ContentNegotiationManagerFactoryBean} with default settings. - */ - protected ContentNegotiationManager initContentNegotiationManager() { - ContentNegotiationManagerFactoryBean factory = new ContentNegotiationManagerFactoryBean(); - factory.afterPropertiesSet(); - return factory.getObject(); - } - - /** * Processes a resource request. *

Checks for the existence of the requested resource in the configured list of locations. 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 52feb87d3f2..c78f75739ef 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 @@ -281,6 +281,34 @@ public class ResourceHttpRequestHandlerTests { assertEquals("h1 { color:red; }", this.response.getContentAsString()); } + @Test // SPR-14368 + public void getResourceWithMediaTypeResolvedThroughServletContext() throws Exception { + MockServletContext servletContext = new MockServletContext() { + + @Override + public String getMimeType(String filePath) { + return "foo/bar"; + } + + @Override + public String getVirtualServerName() { + return null; + } + }; + + List paths = Collections.singletonList(new ClassPathResource("test/", getClass())); + this.handler = new ResourceHttpRequestHandler(); + this.handler.setServletContext(servletContext); + this.handler.setLocations(paths); + this.handler.afterPropertiesSet(); + + this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css"); + this.handler.handleRequest(this.request, this.response); + + assertEquals("foo/bar", this.response.getContentType()); + assertEquals("h1 { color:red; }", this.response.getContentAsString()); + } + @Test public void invalidPath() throws Exception { for (HttpMethod method : HttpMethod.values()) {