Class ResourceWebHandler

java.lang.Object
org.springframework.web.reactive.resource.ResourceWebHandler
All Implemented Interfaces:
InitializingBean, WebHandler

public class ResourceWebHandler extends Object implements WebHandler, InitializingBean
HttpRequestHandler that serves static resources in an optimized way according to the guidelines of Page Speed, YSlow, etc.

The "locations" property takes a list of Spring Resource locations from which static resources are allowed to be served by this handler. Resources could be served from a classpath location, e.g. "classpath:/META-INF/public-web-resources/", allowing convenient packaging and serving of resources such as .js, .css, and others in jar files.

This request handler may also be configured with a resourcesResolver and resourceTransformer chains to support arbitrary resolution and transformation of resources being served. By default a PathResourceResolver simply finds resources based on the configured "locations". An application can configure additional resolvers and transformers such as the VersionResourceResolver which can resolve and prepare URLs for resources with a version in the URL.

This handler also properly evaluates the Last-Modified header (if present) so that a 304 status code will be returned as appropriate, avoiding unnecessary overhead for resources that are already cached by the client.

Since:
5.0
Author:
Rossen Stoyanchev, Brian Clozel, Juergen Hoeller
  • Constructor Details

    • ResourceWebHandler

      public ResourceWebHandler()
  • Method Details

    • setResourceLoader

      public void setResourceLoader(ResourceLoader resourceLoader)
      Provide the ResourceLoader to load location values with.
      Since:
      5.1
    • setLocationValues

      public void setLocationValues(List<String> locationValues)
      Accepts a list of String-based location values to be resolved into Resource locations.
      Since:
      5.1
    • getLocationValues

      public List<String> getLocationValues()
      Return the configured location values.
      Since:
      5.1
    • setLocations

      public void setLocations(@Nullable List<Resource> locations)
      Set the List of Resource paths to use as sources for serving static resources.
    • getLocations

      public List<Resource> getLocations()
      Return the List of Resource paths to use as sources for serving static resources.

      Note that if locationValues are provided, instead of loaded Resource-based locations, this method will return empty until after initialization via afterPropertiesSet().

      Note: As of 5.3.11 the list of locations may be filtered to exclude those that don't actually exist and therefore the list returned from this method may be a subset of all given locations. See setOptimizeLocations(boolean).

      See Also:
    • setResourceResolvers

      public void setResourceResolvers(@Nullable List<ResourceResolver> resourceResolvers)
      Configure the list of ResourceResolvers to use.

      By default PathResourceResolver is configured. If using this property, it is recommended to add PathResourceResolver as the last resolver.

    • getResourceResolvers

      public List<ResourceResolver> getResourceResolvers()
      Return the list of configured resource resolvers.
    • setResourceTransformers

      public void setResourceTransformers(@Nullable List<ResourceTransformer> resourceTransformers)
      Configure the list of ResourceTransformers to use.

      By default no transformers are configured for use.

    • getResourceTransformers

      public List<ResourceTransformer> getResourceTransformers()
      Return the list of configured resource transformers.
    • setResourceHttpMessageWriter

      public void setResourceHttpMessageWriter(@Nullable ResourceHttpMessageWriter httpMessageWriter)
      Configure the ResourceHttpMessageWriter to use.

      By default a ResourceHttpMessageWriter will be configured.

    • getResourceHttpMessageWriter

      @Nullable public ResourceHttpMessageWriter getResourceHttpMessageWriter()
      Return the configured resource message writer.
    • setCacheControl

      public void setCacheControl(@Nullable CacheControl cacheControl)
      Set the CacheControl instance to build the Cache-Control HTTP response header.
    • getCacheControl

      @Nullable public CacheControl getCacheControl()
      Return the CacheControl instance to build the Cache-Control HTTP response header.
    • setUseLastModified

      public void setUseLastModified(boolean useLastModified)
      Set whether we should look at the Resource.lastModified() when serving resources and use this information to drive "Last-Modified" HTTP response headers.

      This option is enabled by default and should be turned off if the metadata of the static files should be ignored.

      Since:
      5.3
    • isUseLastModified

      public boolean isUseLastModified()
      Return whether the Resource.lastModified() information is used to drive HTTP responses when serving static resources.
      Since:
      5.3
    • setOptimizeLocations

      public void setOptimizeLocations(boolean optimizeLocations)
      Set whether to optimize the specified locations through an existence check on startup, filtering non-existing directories upfront so that they do not have to be checked on every resource access.

      The default is false, for defensiveness against zip files without directory entries which are unable to expose the existence of a directory upfront. Switch this flag to true for optimized access in case of a consistent jar layout with directory entries.

      Since:
      5.3.13
    • isOptimizeLocations

      public boolean isOptimizeLocations()
      Return whether to optimize the specified locations through an existence check on startup, filtering non-existing directories upfront so that they do not have to be checked on every resource access.
      Since:
      5.3.13
    • setMediaTypes

      public void setMediaTypes(Map<String,MediaType> mediaTypes)
      Add mappings between file extensions extracted from the filename of static Resources and the media types to use for the response.

      Use of this method is typically not necessary since mappings can be also determined via MediaTypeFactory.getMediaType(Resource).

      Parameters:
      mediaTypes - media type mappings
      Since:
      5.3.2
    • getMediaTypes

      public Map<String,MediaType> getMediaTypes()
      Return the configured media type mappings.
      Since:
      5.3.2
    • afterPropertiesSet

      public void afterPropertiesSet() throws Exception
      Description copied from interface: InitializingBean
      Invoked by the containing BeanFactory after it has set all bean properties and satisfied BeanFactoryAware, ApplicationContextAware etc.

      This method allows the bean instance to perform validation of its overall configuration and final initialization when all bean properties have been set.

      Specified by:
      afterPropertiesSet in interface InitializingBean
      Throws:
      Exception - in the event of misconfiguration (such as failure to set an essential property) or if initialization fails for any other reason
    • initAllowedLocations

      protected void initAllowedLocations()
      Look for a PathResourceResolver among the configured resource resolvers and set its allowedLocations property (if empty) to match the locations configured on this class.
    • handle

      public reactor.core.publisher.Mono<Void> handle(ServerWebExchange exchange)
      Processes a resource request.

      Checks for the existence of the requested resource in the configured list of locations. If the resource does not exist, a 404 response will be returned to the client. If the resource exists, the request will be checked for the presence of the Last-Modified header, and its value will be compared against the last-modified timestamp of the given resource, returning a 304 status code if the Last-Modified value is greater. If the resource is newer than the Last-Modified value, or the header is not present, the content resource of the resource will be written to the response with caching headers set to expire one year in the future.

      Specified by:
      handle in interface WebHandler
      Parameters:
      exchange - the current server exchange
      Returns:
      Mono<Void> to indicate when request handling is complete
    • getResource

      protected reactor.core.publisher.Mono<Resource> getResource(ServerWebExchange exchange)
    • processPath

      protected String processPath(String path)
      Process the given resource path.

      The default implementation replaces:

      • Backslash with forward slash.
      • Duplicate occurrences of slash with a single slash.
      • Any combination of leading slash and control characters (00-1F and 7F) with a single "/" or "". For example " / // foo/bar" becomes "/foo/bar".
      Since:
      3.2.12
    • isInvalidPath

      protected boolean isInvalidPath(String path)
      Identifies invalid resource paths. By default rejects:

      Note: this method assumes that leading, duplicate '/' or control characters (e.g. white space) have been trimmed so that the path starts predictably with a single '/' or does not have one.

      Parameters:
      path - the path to validate
      Returns:
      true if the path is invalid, false otherwise
    • setHeaders

      protected void setHeaders(ServerWebExchange exchange, Resource resource, @Nullable MediaType mediaType) throws IOException
      Set headers on the response. Called for both GET and HEAD requests.
      Parameters:
      exchange - current exchange
      resource - the identified resource (never null)
      mediaType - the resource's media type (never null)
      Throws:
      IOException
    • toString

      public String toString()
      Overrides:
      toString in class Object