Set ETag header with VersionResourceResolver

Prior to this change, VersionResourceResolver and VersionStrategy would
resolve static resources using version strings. They assist
ResourceHttpRequestHandler with serving static resources. The
RequestHandler itself can be configured with HTTP caching strategies to
set Cache-Control headers.

In order to have a complete strategy with Cache-Control and ETag
response headers, developers can't reuse that version string information
and have to rely on other mechanisms (like ShallowEtagHeaderFilter).

This commit makes VersionResourceResolver use that version string to set
it as a request attribute, which will be used by the
ResourceHttpRequestHandler to write an ETag response header.

Issue: SPR-13382
This commit is contained in:
Brian Clozel
2015-08-25 16:49:10 +02:00
parent 0b9c3de320
commit 190eb6ace1
5 changed files with 37 additions and 9 deletions

View File

@@ -87,6 +87,7 @@ public class ResourceHttpRequestHandlerTests {
@Test
public void getResource() throws Exception {
this.request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "foo.css");
this.request.setAttribute(VersionResourceResolver.RESOURCE_VERSION_ATTRIBUTE, "versionString");
this.handler.handleRequest(this.request, this.response);
assertEquals("text/css", this.response.getContentType());
@@ -94,6 +95,7 @@ public class ResourceHttpRequestHandlerTests {
assertEquals("max-age=3600", this.response.getHeader("Cache-Control"));
assertTrue(this.response.containsHeader("Last-Modified"));
assertEquals(this.response.getHeader("Last-Modified"), resourceLastModifiedDate("test/foo.css"));
assertEquals("\"versionString\"", this.response.getHeader("ETag"));
assertEquals("h1 { color:red; }", this.response.getContentAsString());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2002-2014 the original author or authors.
* Copyright 2002-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@ import org.junit.Test;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.mock.web.test.MockHttpServletRequest;
import static org.junit.Assert.*;
import static org.mockito.BDDMockito.*;
@@ -135,17 +136,19 @@ public class VersionResourceResolverTests {
String version = "version";
String file = "bar.css";
Resource expected = new ClassPathResource("test/" + file, getClass());
given(this.chain.resolveResource(null, versionFile, this.locations)).willReturn(null);
given(this.chain.resolveResource(null, file, this.locations)).willReturn(expected);
MockHttpServletRequest request = new MockHttpServletRequest("GET", "/resources/bar-version.css");
given(this.chain.resolveResource(request, versionFile, this.locations)).willReturn(null);
given(this.chain.resolveResource(request, file, this.locations)).willReturn(expected);
given(this.versionStrategy.extractVersion(versionFile)).willReturn(version);
given(this.versionStrategy.removeVersion(versionFile, version)).willReturn(file);
given(this.versionStrategy.getResourceVersion(expected)).willReturn(version);
this.resolver
.setStrategyMap(Collections.singletonMap("/**", this.versionStrategy));
Resource actual = this.resolver.resolveResourceInternal(null, versionFile, this.locations, this.chain);
Resource actual = this.resolver.resolveResourceInternal(request, versionFile, this.locations, this.chain);
assertEquals(expected, actual);
verify(this.versionStrategy, times(1)).getResourceVersion(expected);
assertEquals(version, request.getAttribute(VersionResourceResolver.RESOURCE_VERSION_ATTRIBUTE));
}
@Test