Skip to content

Commit c9c3857

Browse files
committed
Update section on resource handler config
Issue: SPR-14036
1 parent 49b872e commit c9c3857

File tree

1 file changed

+42
-53
lines changed

1 file changed

+42
-53
lines changed

src/asciidoc/index.adoc

Lines changed: 42 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,7 +1050,7 @@ method has been added.
10501050
has been expanded with new abstractions `ResourceResolver`, `ResourceTransformer`,
10511051
and `ResourceUrlProvider`. A number of built-in implementations provide support
10521052
for versioned resource URLs (for effective HTTP caching), locating gzipped resources,
1053-
generating an HTML 5 AppCache manifests, and more.
1053+
generating an HTML 5 AppCache manifests, and more. See <<mvc-config-static-resources>>.
10541054
* JDK 1.8's `java.util.Optional` is now supported for `@RequestParam`, `@RequestHeader`,
10551055
and `@MatrixVariable` controller method arguments.
10561056
* `ListenableFuture` is supported as a return value alternative to `DeferredResult`
@@ -34345,82 +34345,71 @@ And in XML:
3434534345
----
3434634346

3434734347
When serving resources that may change when a new version of the application is
34348-
deployed, it is recommended that you incorporate a version string into the mapping
34349-
pattern used to request the resources, so that you may force clients to request the
34350-
newly deployed version of your application's resources. Such a version string can be
34351-
parameterized and accessed using SpEL so that it may be easily managed in a single place
34352-
when deploying new versions.
34353-
34354-
As an example, let's consider an application that uses a performance-optimized custom
34355-
build (as recommended) of the Dojo JavaScript library in production, and that the build
34356-
is generally deployed within the web application at a path of
34357-
`/public-resources/dojo/dojo.js`. Since different parts of Dojo may be incorporated into
34358-
the custom build for each new version of the application, the client web browsers need
34359-
to be forced to re-download that custom-built `dojo.js` resource any time a new version
34360-
of the application is deployed. A simple way to achieve this would be to manage the
34361-
version of the application in a properties file, such as:
34348+
deployed it is recommended that you incorporate a version string into the mapping
34349+
pattern used to request the resources so that you may force clients to request the
34350+
newly deployed version of your application's resources. Support for versioned URLs is
34351+
built into the framework and can be enabled by configuring a resource chain
34352+
on the resource handler. The chain consists of one more `ResourceResolver`
34353+
instances followed by one or more `ResourceTransformer` instances. Together they
34354+
can provide arbitrary resolution and transformation of resources.
3436234355

34363-
[literal]
34364-
[subs="verbatim,quotes"]
34365-
----
34366-
application.version=1.0.0
34367-
----
34368-
34369-
and then to make the properties file's values accessible to SpEL as a bean using the
34370-
`util:properties` tag:
34371-
34372-
[source,xml,indent=0]
34373-
[subs="verbatim,quotes"]
34374-
----
34375-
<util:properties id="applicationProps" location="/WEB-INF/spring/application.properties"/>
34376-
----
34356+
The built-in `VersionResourceResolver` can be configured with different strategies.
34357+
For example a `FixedVersionStrategy` can use a property, a date, or other as the version.
34358+
A `ContentVersionStrategy` uses an MD5 hash computed from the content of the resource
34359+
(known as "fingerprinting" URLs).
3437734360

34378-
With the application version now accessible via SpEL, we can incorporate this into the
34379-
use of the `resources` tag:
34361+
`ContentVersionStrategy` is a good default choice to use except in cases where
34362+
it cannot be used (e.g. with JavaScript module loaders). You can configure
34363+
different version strategies against different patterns as shown below. Keep in mind
34364+
also that computing content-based versions is expensive and therefore resource chain
34365+
caching should be enabled in production.
3438034366

34381-
[source,xml,indent=0]
34382-
[subs="verbatim,quotes"]
34383-
----
34384-
<mvc:resources mapping="/resources-#{applicationProps['application.version']}/**" location="/public-resources/"/>
34385-
----
34386-
34387-
In Java, you can use the `@PropertySouce` annotation and then inject the `Environment`
34388-
abstraction for access to all defined properties:
34367+
Java config example;
3438934368

3439034369
[source,java,indent=0]
3439134370
[subs="verbatim,quotes"]
3439234371
----
3439334372
@Configuration
3439434373
@EnableWebMvc
34395-
@PropertySource("/WEB-INF/spring/application.properties")
3439634374
public class WebConfig extends WebMvcConfigurerAdapter {
3439734375

34398-
@Inject Environment env;
34399-
3440034376
@Override
3440134377
public void addResourceHandlers(ResourceHandlerRegistry registry) {
34402-
registry.addResourceHandler(
34403-
"/resources-" + env.getProperty("application.version") + "/**")
34404-
.addResourceLocations("/public-resources/");
34378+
registry.addResourceHandler("/resources/**")
34379+
.addResourceLocations("/public-resources/")
34380+
.resourceChain(true).addResolver(
34381+
new VersionResourceResolver().addContentVersionStrategy("/**"));
3440534382
}
3440634383

3440734384
}
3440834385
----
3440934386

34410-
and finally, to request the resource with the proper URL, we can take advantage of the
34411-
Spring JSP tags:
34387+
XML example:
3441234388

3441334389
[source,xml,indent=0]
3441434390
[subs="verbatim,quotes"]
3441534391
----
34416-
<spring:eval expression="@applicationProps['application.version']" var="applicationVersion"/>
34392+
<mvc:resources mapping="/resources/**" location="/public-resources/">
34393+
<mvc:resource-chain>
34394+
<mvc:resource-cache />
34395+
<mvc:resolvers>
34396+
<mvc:version-resolver>
34397+
<mvc:content-version-strategy patterns="/**"/>
34398+
</mvc:version-resolver>
34399+
</mvc:resolvers>
34400+
</mvc:resource-chain>
34401+
</mvc:resources>
34402+
----
34403+
34404+
In order for the above to work the application must also
34405+
render URLs with versions. The easiest way to do that is to configure the
34406+
`ResourceUrlEncodingFilter` which wraps the response and overrides its `encodeURL` method.
34407+
This will work in JSPs, FreeMarker, Velocity, and any other view technology that calls
34408+
the response `encodeURL` method. Alternatively, an application can also inject and
34409+
use directly the `ResourceUrlProvider` bean, which is automatically declared with the MVC
34410+
Java config and the MVC namespace.
3441734411

34418-
<spring:url value="/resources-{applicationVersion}" var="resourceUrl">
34419-
<spring:param name="applicationVersion" value="${applicationVersion}"/>
34420-
</spring:url>
3442134412

34422-
<script src="${resourceUrl}/dojo/dojo.js" type="text/javascript"> </script>
34423-
----
3442434413

3442534414

3442634415
[[mvc-default-servlet-handler]]

0 commit comments

Comments
 (0)