@ -1,5 +1,5 @@
/ *
/ *
* Copyright 2002 - 2019 the original author or authors .
* Copyright 2002 - 2020 the original author or authors .
*
*
* Licensed under the Apache License , Version 2 . 0 ( the "License" ) ;
* Licensed under the Apache License , Version 2 . 0 ( the "License" ) ;
* you may not use this file except in compliance with the License .
* you may not use this file except in compliance with the License .
@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.Collections ;
import java.util.Collections ;
import java.util.HashMap ;
import java.util.HashMap ;
import java.util.List ;
import java.util.List ;
import java.util.Locale ;
import java.util.Map ;
import java.util.Map ;
import java.util.stream.Collectors ;
import java.util.stream.Collectors ;
@ -43,6 +44,7 @@ import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod ;
import org.springframework.http.HttpMethod ;
import org.springframework.http.HttpRange ;
import org.springframework.http.HttpRange ;
import org.springframework.http.MediaType ;
import org.springframework.http.MediaType ;
import org.springframework.http.MediaTypeFactory ;
import org.springframework.http.converter.ResourceHttpMessageConverter ;
import org.springframework.http.converter.ResourceHttpMessageConverter ;
import org.springframework.http.converter.ResourceRegionHttpMessageConverter ;
import org.springframework.http.converter.ResourceRegionHttpMessageConverter ;
import org.springframework.http.server.ServletServerHttpRequest ;
import org.springframework.http.server.ServletServerHttpRequest ;
@ -56,8 +58,6 @@ import org.springframework.util.StringUtils;
import org.springframework.util.StringValueResolver ;
import org.springframework.util.StringValueResolver ;
import org.springframework.web.HttpRequestHandler ;
import org.springframework.web.HttpRequestHandler ;
import org.springframework.web.accept.ContentNegotiationManager ;
import org.springframework.web.accept.ContentNegotiationManager ;
import org.springframework.web.accept.PathExtensionContentNegotiationStrategy ;
import org.springframework.web.accept.ServletPathExtensionContentNegotiationStrategy ;
import org.springframework.web.context.request.ServletWebRequest ;
import org.springframework.web.context.request.ServletWebRequest ;
import org.springframework.web.cors.CorsConfiguration ;
import org.springframework.web.cors.CorsConfiguration ;
import org.springframework.web.cors.CorsConfigurationSource ;
import org.springframework.web.cors.CorsConfigurationSource ;
@ -129,8 +129,7 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
@Nullable
@Nullable
private ContentNegotiationManager contentNegotiationManager ;
private ContentNegotiationManager contentNegotiationManager ;
@Nullable
private final Map < String , MediaType > mediaTypes = new HashMap < > ( 4 ) ;
private PathExtensionContentNegotiationStrategy contentNegotiationStrategy ;
@Nullable
@Nullable
private CorsConfiguration corsConfiguration ;
private CorsConfiguration corsConfiguration ;
@ -262,7 +261,11 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
* media types for resources being served . If the manager contains a path
* media types for resources being served . If the manager contains a path
* extension strategy it will be checked for registered file extension .
* extension strategy it will be checked for registered file extension .
* @since 4 . 3
* @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 ) {
public void setContentNegotiationManager ( @Nullable ContentNegotiationManager contentNegotiationManager ) {
this . contentNegotiationManager = contentNegotiationManager ;
this . contentNegotiationManager = contentNegotiationManager ;
}
}
@ -270,12 +273,38 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
/ * *
/ * *
* Return the configured content negotiation manager .
* Return the configured content negotiation manager .
* @since 4 . 3
* @since 4 . 3
* @deprecated as of 5 . 2 . 4 .
* /
* /
@Nullable
@Nullable
@Deprecated
public ContentNegotiationManager getContentNegotiationManager ( ) {
public ContentNegotiationManager getContentNegotiationManager ( ) {
return this . contentNegotiationManager ;
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
* response .
* < p > Use of this method is typically not necessary since mappings are
* otherwise determined via
* { @link javax . servlet . ServletContext # getMimeType ( String ) } or via
* { @link MediaTypeFactory # getMediaType ( Resource ) } .
* @param mediaTypes media type mappings
* @since 5 . 2 . 4
* /
public void setMediaTypes ( Map < String , MediaType > mediaTypes ) {
mediaTypes . forEach ( ( ext , mediaType ) - >
this . mediaTypes . put ( ext . toLowerCase ( Locale . ENGLISH ) , mediaType ) ) ;
}
/ * *
* Return the { @link # setMediaTypes ( Map ) configured } media types .
* @since 5 . 2 . 4
* /
public Map < String , MediaType > getMediaTypes ( ) {
return this . mediaTypes ;
}
/ * *
/ * *
* Specify the CORS configuration for resources served by this handler .
* Specify the CORS configuration for resources served by this handler .
* < p > By default this is not set in which allows cross - origin requests .
* < p > By default this is not set in which allows cross - origin requests .
@ -344,7 +373,17 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
this . resourceRegionHttpMessageConverter = new ResourceRegionHttpMessageConverter ( ) ;
this . resourceRegionHttpMessageConverter = new ResourceRegionHttpMessageConverter ( ) ;
}
}
this . contentNegotiationStrategy = initContentNegotiationStrategy ( ) ;
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 ( ) {
private void resolveResourceLocations ( ) {
@ -412,26 +451,20 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
}
}
/ * *
/ * *
* Initialize the content negotiation strategy depending on the { @code ContentNegotiationManager }
* Initialize the strategy to use to determine the media type for a resource .
* setup and the availability of a { @code ServletContext } .
* @deprecated as of 5 . 2 . 4 this method returns { @code null } , and if a
* @see ServletPathExtensionContentNegotiationStrategy
* sub - class returns an actual instance , the instance is used only as a
* @see PathExtensionContentNegotiationStrategy
* 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 ) } .
* /
* /
protected PathExtensionContentNegotiationStrategy initContentNegotiationStrategy ( ) {
@Nullable
Map < String , MediaType > mediaTypes = null ;
@Deprecated
if ( getContentNegotiationManager ( ) ! = null ) {
@SuppressWarnings ( "deprecation" )
PathExtensionContentNegotiationStrategy strategy =
protected org . springframework . web . accept . PathExtensionContentNegotiationStrategy initContentNegotiationStrategy ( ) {
getContentNegotiationManager ( ) . getStrategy ( PathExtensionContentNegotiationStrategy . class ) ;
return null ;
if ( strategy ! = null ) {
mediaTypes = new HashMap < > ( strategy . getMediaTypes ( ) ) ;
}
}
return ( getServletContext ( ) ! = null ?
new ServletPathExtensionContentNegotiationStrategy ( getServletContext ( ) , mediaTypes ) :
new PathExtensionContentNegotiationStrategy ( mediaTypes ) ) ;
}
}
/ * *
/ * *
* Processes a resource request .
* Processes a resource request .
* < p > Checks for the existence of the requested resource in the configured list of locations .
* < p > Checks for the existence of the requested resource in the configured list of locations .
@ -659,17 +692,40 @@ public class ResourceHttpRequestHandler extends WebContentGenerator
/ * *
/ * *
* Determine the media type for the given request and the resource matched
* Determine the media type for the given request and the resource matched
* to it . This implementation tries to determine the MediaType based on the
* to it . This implementation tries to determine the MediaType using one of
* file extension of the Resource via
* the following lookups based on the resource filename and its path
* { @link ServletPathExtensionContentNegotiationStrategy # getMediaTypeForResource } .
* extension :
* < ol >
* < li > { @link javax . servlet . ServletContext # getMimeType ( String ) }
* < li > { @link # getMediaTypes ( ) }
* < li > { @link MediaTypeFactory # getMediaType ( String ) }
* < / ol >
* @param request the current request
* @param request the current request
* @param resource the resource to check
* @param resource the resource to check
* @return the corresponding media type , or { @code null } if none found
* @return the corresponding media type , or { @code null } if none found
* /
* /
@Nullable
@Nullable
protected MediaType getMediaType ( HttpServletRequest request , Resource resource ) {
protected MediaType getMediaType ( HttpServletRequest request , Resource resource ) {
return ( this . contentNegotiationStrategy ! = null ?
MediaType result = null ;
this . contentNegotiationStrategy . getMediaTypeForResource ( resource ) : null ) ;
String mimeType = request . getServletContext ( ) . getMimeType ( resource . getFilename ( ) ) ;
if ( StringUtils . hasText ( mimeType ) ) {
result = MediaType . parseMediaType ( mimeType ) ;
}
if ( result = = null | | MediaType . APPLICATION_OCTET_STREAM . equals ( result ) ) {
MediaType mediaType = null ;
String filename = resource . getFilename ( ) ;
String ext = StringUtils . getFilenameExtension ( filename ) ;
if ( ext ! = null ) {
mediaType = this . mediaTypes . get ( ext . toLowerCase ( Locale . ENGLISH ) ) ;
}
if ( mediaType = = null ) {
mediaType = MediaTypeFactory . getMediaType ( filename ) . orElse ( null ) ;
}
if ( mediaType ! = null ) {
result = mediaType ;
}
}
return result ;
}
}
/ * *
/ * *