diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java index ac547dbed7..ce2e89e7bb 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/VersionResourceResolver.java @@ -22,11 +22,13 @@ import java.io.InputStream; import java.net.URI; import java.net.URL; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; + import javax.servlet.http.HttpServletRequest; import org.springframework.core.io.AbstractResource; @@ -109,14 +111,26 @@ public class VersionResourceResolver extends AbstractResourceResolver { * fetched from a git commit sha, a property file, or environment variable * and set with SpEL expressions in the configuration (e.g. see {@code @Value} * in Java config). + *

If not done already, variants of the given {@code pathPatterns}, prefixed with + * the {@code version} will be also configured. For example, adding a {@code "/js/**"} path pattern + * will also cofigure automatically a {@code "/v1.0.0/js/**"} with {@code "v1.0.0"} the + * {@code version} String given as an argument. * @param version a version string * @param pathPatterns one or more resource URL path patterns * @return the current instance for chained method invocation * @see FixedVersionStrategy */ public VersionResourceResolver addFixedVersionStrategy(String version, String... pathPatterns) { - addVersionStrategy(new FixedVersionStrategy(version), pathPatterns); - return this; + List patternsList = Arrays.asList(pathPatterns); + List prefixedPatterns = new ArrayList(pathPatterns.length); + String versionPrefix = "/" + version; + for(String pattern : patternsList) { + prefixedPatterns.add(pattern); + if(!pattern.startsWith(versionPrefix) && !patternsList.contains(versionPrefix + pattern)) { + prefixedPatterns.add(versionPrefix + pattern); + } + } + return addVersionStrategy(new FixedVersionStrategy(version), prefixedPatterns.toArray(new String[0])); } /** diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/VersionResourceResolverTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/VersionResourceResolverTests.java index 3f007b8793..d423872638 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/VersionResourceResolverTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/resource/VersionResourceResolverTests.java @@ -21,6 +21,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import org.hamcrest.Matchers; import org.junit.Before; import org.junit.Test; @@ -28,7 +29,7 @@ import org.springframework.core.io.ClassPathResource; import org.springframework.core.io.Resource; import org.springframework.mock.web.test.MockHttpServletRequest; -import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.*; import static org.junit.Assert.*; import static org.mockito.BDDMockito.*; @@ -168,4 +169,18 @@ public class VersionResourceResolverTests { assertEquals(jsStrategy, this.resolver.getStrategyForPath("bar/foo.js")); } + // SPR-13883 + @Test + public void shouldConfigureFixedPrefixAutomatically() throws Exception { + + this.resolver.addFixedVersionStrategy("fixedversion", "/js/**", "/css/**", "/fixedversion/css/**"); + + assertThat(this.resolver.getStrategyMap().size(), is(4)); + assertThat(this.resolver.getStrategyForPath("/js/something.js"), Matchers.instanceOf(FixedVersionStrategy.class)); + assertThat(this.resolver.getStrategyForPath("/fixedversion/js/something.js"), Matchers.instanceOf(FixedVersionStrategy.class)); + assertThat(this.resolver.getStrategyForPath("/css/something.css"), Matchers.instanceOf(FixedVersionStrategy.class)); + assertThat(this.resolver.getStrategyForPath("/fixedversion/css/something.css"), Matchers.instanceOf(FixedVersionStrategy.class)); + } + + }