|
|
|
@ -31,7 +31,6 @@ import org.apache.commons.logging.Log; |
|
|
|
import org.apache.commons.logging.LogFactory; |
|
|
|
import org.apache.commons.logging.LogFactory; |
|
|
|
|
|
|
|
|
|
|
|
import org.springframework.beans.factory.InitializingBean; |
|
|
|
import org.springframework.beans.factory.InitializingBean; |
|
|
|
import org.springframework.beans.factory.SmartInitializingSingleton; |
|
|
|
|
|
|
|
import org.springframework.core.io.Resource; |
|
|
|
import org.springframework.core.io.Resource; |
|
|
|
import org.springframework.core.io.support.ResourceRegion; |
|
|
|
import org.springframework.core.io.support.ResourceRegion; |
|
|
|
import org.springframework.http.HttpHeaders; |
|
|
|
import org.springframework.http.HttpHeaders; |
|
|
|
@ -91,7 +90,7 @@ import org.springframework.web.servlet.support.WebContentGenerator; |
|
|
|
* @since 3.0.4 |
|
|
|
* @since 3.0.4 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class ResourceHttpRequestHandler extends WebContentGenerator |
|
|
|
public class ResourceHttpRequestHandler extends WebContentGenerator |
|
|
|
implements HttpRequestHandler, InitializingBean, SmartInitializingSingleton, CorsConfigurationSource { |
|
|
|
implements HttpRequestHandler, InitializingBean, CorsConfigurationSource { |
|
|
|
|
|
|
|
|
|
|
|
// Servlet 3.1 setContentLengthLong(long) available?
|
|
|
|
// Servlet 3.1 setContentLengthLong(long) available?
|
|
|
|
private static final boolean contentLengthLongAvailable = |
|
|
|
private static final boolean contentLengthLongAvailable = |
|
|
|
@ -112,7 +111,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator |
|
|
|
|
|
|
|
|
|
|
|
private ContentNegotiationManager contentNegotiationManager; |
|
|
|
private ContentNegotiationManager contentNegotiationManager; |
|
|
|
|
|
|
|
|
|
|
|
private PathExtensionContentNegotiationStrategy pathExtensionStrategy; |
|
|
|
private PathExtensionContentNegotiationStrategy contentNegotiationStrategy; |
|
|
|
|
|
|
|
|
|
|
|
private CorsConfiguration corsConfiguration; |
|
|
|
private CorsConfiguration corsConfiguration; |
|
|
|
|
|
|
|
|
|
|
|
@ -253,16 +252,20 @@ public class ResourceHttpRequestHandler extends WebContentGenerator |
|
|
|
logger.warn("Locations list is empty. No resources will be served unless a " + |
|
|
|
logger.warn("Locations list is empty. No resources will be served unless a " + |
|
|
|
"custom ResourceResolver is configured as an alternative to PathResourceResolver."); |
|
|
|
"custom ResourceResolver is configured as an alternative to PathResourceResolver."); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (this.resourceResolvers.isEmpty()) { |
|
|
|
if (this.resourceResolvers.isEmpty()) { |
|
|
|
this.resourceResolvers.add(new PathResourceResolver()); |
|
|
|
this.resourceResolvers.add(new PathResourceResolver()); |
|
|
|
} |
|
|
|
} |
|
|
|
initAllowedLocations(); |
|
|
|
initAllowedLocations(); |
|
|
|
|
|
|
|
|
|
|
|
if (this.resourceHttpMessageConverter == null) { |
|
|
|
if (this.resourceHttpMessageConverter == null) { |
|
|
|
this.resourceHttpMessageConverter = new ResourceHttpMessageConverter(); |
|
|
|
this.resourceHttpMessageConverter = new ResourceHttpMessageConverter(); |
|
|
|
} |
|
|
|
} |
|
|
|
if (this.resourceRegionHttpMessageConverter == null) { |
|
|
|
if (this.resourceRegionHttpMessageConverter == null) { |
|
|
|
this.resourceRegionHttpMessageConverter = new ResourceRegionHttpMessageConverter(); |
|
|
|
this.resourceRegionHttpMessageConverter = new ResourceRegionHttpMessageConverter(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this.contentNegotiationStrategy = initContentNegotiationStrategy(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
@ -285,11 +288,12 @@ public class ResourceHttpRequestHandler extends WebContentGenerator |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Override |
|
|
|
/** |
|
|
|
public void afterSingletonsInstantiated() { |
|
|
|
* Initialize the content negotiation strategy depending on the {@code ContentNegotiationManager} |
|
|
|
this.pathExtensionStrategy = initContentNegotiationStrategy(); |
|
|
|
* setup and the availability of a {@code ServletContext}. |
|
|
|
} |
|
|
|
* @see ServletPathExtensionContentNegotiationStrategy |
|
|
|
|
|
|
|
* @see PathExtensionContentNegotiationStrategy |
|
|
|
|
|
|
|
*/ |
|
|
|
protected PathExtensionContentNegotiationStrategy initContentNegotiationStrategy() { |
|
|
|
protected PathExtensionContentNegotiationStrategy initContentNegotiationStrategy() { |
|
|
|
Map<String, MediaType> mediaTypes = null; |
|
|
|
Map<String, MediaType> mediaTypes = null; |
|
|
|
if (getContentNegotiationManager() != null) { |
|
|
|
if (getContentNegotiationManager() != null) { |
|
|
|
@ -299,9 +303,9 @@ public class ResourceHttpRequestHandler extends WebContentGenerator |
|
|
|
mediaTypes = new HashMap<>(strategy.getMediaTypes()); |
|
|
|
mediaTypes = new HashMap<>(strategy.getMediaTypes()); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
return (getServletContext() != null) ? |
|
|
|
return (getServletContext() != null ? |
|
|
|
new ServletPathExtensionContentNegotiationStrategy(getServletContext(), mediaTypes) : |
|
|
|
new ServletPathExtensionContentNegotiationStrategy(getServletContext(), mediaTypes) : |
|
|
|
new PathExtensionContentNegotiationStrategy(mediaTypes); |
|
|
|
new PathExtensionContentNegotiationStrategy(mediaTypes)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -514,7 +518,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator |
|
|
|
* @return the corresponding media type, or {@code null} if none found |
|
|
|
* @return the corresponding media type, or {@code null} if none found |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
protected MediaType getMediaType(HttpServletRequest request, Resource resource) { |
|
|
|
protected MediaType getMediaType(HttpServletRequest request, Resource resource) { |
|
|
|
return this.pathExtensionStrategy.getMediaTypeForResource(resource); |
|
|
|
return this.contentNegotiationStrategy.getMediaTypeForResource(resource); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
|