Update resource handler XML Namespace

This change introduces a new <mvc:resource-chain/> tag that mirrors
the ResourceChainRegistration java config counterpart.

Resolvers and Transformers can be registered with bean/ref tags, and
specific tags have been created for <mvc:version-resovlver> and
<mvc:resource-cache> in order to make common configurations easier.

Note that a specific "auto-configuration" attribute on the
resource-chain allows to completely disable default registration of
Resolvers and Transformers (sane defaults considered by the Framework).

  <mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/">
      <mvc:resource-chain>
        <mvc:resource-cache cache="resourceCache"/>
        <mvc:resolvers>
          <mvc:version-resolver>
            <mvc:fixed-version-strategy version="abc" patterns="/**/*.js"/>
            <mvc:content-version-strategy patterns="/**"/>
          </mvc:version-resolver>
        </mvc:resolvers>
        <mvc:transformers>
          <bean class="org.springframework.web.servlet.resource.AppCacheManifestTransformer"/>
        </mvc:transformers>
      </mvc:resource-chain>
  </mvc:resources>

This also fixes a typo in the class name of
AppCacheManifestResourceTransfo*r*mer.

Issue: SPR-12129
This commit is contained in:
Brian Clozel
2014-08-29 15:36:51 +02:00
parent 8008e466aa
commit d9f4016c35
9 changed files with 386 additions and 68 deletions

View File

@@ -16,6 +16,8 @@
package org.springframework.web.servlet.config;
import static org.junit.Assert.*;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
@@ -30,6 +32,7 @@ import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.cache.concurrent.ConcurrentMapCache;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.core.Ordered;
import org.springframework.core.convert.ConversionService;
@@ -76,14 +79,19 @@ import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import org.springframework.web.servlet.mvc.method.annotation.MvcUriComponentsBuilder;
import org.springframework.web.servlet.resource.AppCacheManifestTransformer;
import org.springframework.web.servlet.resource.CachingResourceResolver;
import org.springframework.web.servlet.resource.CachingResourceTransformer;
import org.springframework.web.servlet.resource.ContentVersionStrategy;
import org.springframework.web.servlet.resource.CssLinkResourceTransformer;
import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
import org.springframework.web.servlet.resource.FixedVersionStrategy;
import org.springframework.web.servlet.resource.GzipResourceResolver;
import org.springframework.web.servlet.resource.PathResourceResolver;
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
import org.springframework.web.servlet.resource.ResourceResolver;
import org.springframework.web.servlet.resource.ResourceTransformer;
import org.springframework.web.servlet.resource.VersionResourceResolver;
import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
import org.springframework.web.servlet.view.groovy.GroovyMarkupConfigurer;
import org.springframework.web.servlet.view.groovy.GroovyMarkupViewResolver;
@@ -96,8 +104,6 @@ import org.springframework.web.servlet.view.tiles3.TilesViewResolver;
import org.springframework.web.servlet.view.velocity.VelocityConfigurer;
import org.springframework.web.servlet.view.velocity.VelocityViewResolver;
import static org.junit.Assert.*;
/**
* Tests loading actual MVC namespace configuration.
*
@@ -328,7 +334,7 @@ public class MvcNamespaceTests {
@Test
public void testResourcesWithResolversTransformers() throws Exception {
loadBeanDefinitions("mvc-config-resources-resolvers-transformers.xml", 10);
loadBeanDefinitions("mvc-config-resources-chain.xml", 8);
SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class);
assertNotNull(mapping);
@@ -338,14 +344,54 @@ public class MvcNamespaceTests {
assertNotNull(handler);
List<ResourceResolver> resolvers = handler.getResourceResolvers();
assertThat(resolvers, Matchers.hasSize(2));
assertThat(resolvers.get(0), Matchers.instanceOf(PathResourceResolver.class));
assertThat(resolvers, Matchers.hasSize(3));
assertThat(resolvers.get(0), Matchers.instanceOf(CachingResourceResolver.class));
assertThat(resolvers.get(1), Matchers.instanceOf(VersionResourceResolver.class));
assertThat(resolvers.get(2), Matchers.instanceOf(PathResourceResolver.class));
CachingResourceResolver cachingResolver = (CachingResourceResolver) resolvers.get(0);
assertThat(cachingResolver.getCache(), Matchers.instanceOf(TestResourceCache.class));
VersionResourceResolver versionResolver = (VersionResourceResolver) resolvers.get(1);
assertThat(versionResolver.getStrategyMap().get("/**/*.js"),
Matchers.instanceOf(FixedVersionStrategy.class));
assertThat(versionResolver.getStrategyMap().get("/**"),
Matchers.instanceOf(ContentVersionStrategy.class));
List<ResourceTransformer> transformers = handler.getResourceTransformers();
assertThat(transformers, Matchers.hasSize(3));
assertThat(transformers.get(0), Matchers.instanceOf(CachingResourceTransformer.class));
assertThat(transformers.get(1), Matchers.instanceOf(CssLinkResourceTransformer.class));
assertThat(transformers.get(2), Matchers.instanceOf(AppCacheManifestTransformer.class));
}
@Test
public void testResourcesWithResolversTransformersCustom() throws Exception {
loadBeanDefinitions("mvc-config-resources-chain-no-auto.xml", 9);
SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class);
assertNotNull(mapping);
assertNotNull(mapping.getUrlMap().get("/resources/**"));
ResourceHttpRequestHandler handler = appContext.getBean((String)mapping.getUrlMap().get("/resources/**"),
ResourceHttpRequestHandler.class);
assertNotNull(handler);
List<ResourceResolver> resolvers = handler.getResourceResolvers();
assertThat(resolvers, Matchers.hasSize(3));
assertThat(resolvers.get(0), Matchers.instanceOf(VersionResourceResolver.class));
assertThat(resolvers.get(1), Matchers.instanceOf(GzipResourceResolver.class));
assertThat(resolvers.get(2), Matchers.instanceOf(PathResourceResolver.class));
VersionResourceResolver versionResolver = (VersionResourceResolver) resolvers.get(0);
assertThat(versionResolver.getStrategyMap().get("/**/*.js"),
Matchers.instanceOf(FixedVersionStrategy.class));
assertThat(versionResolver.getStrategyMap().get("/**"),
Matchers.instanceOf(ContentVersionStrategy.class));
List<ResourceTransformer> transformers = handler.getResourceTransformers();
assertThat(transformers, Matchers.hasSize(2));
assertThat(transformers.get(0), Matchers.instanceOf(CachingResourceTransformer.class));
assertThat(transformers.get(1), Matchers.instanceOf(CssLinkResourceTransformer.class));
assertThat(transformers.get(1), Matchers.instanceOf(AppCacheManifestTransformer.class));
}
@Test
@@ -823,5 +869,11 @@ public class MvcNamespaceTests {
public static class TestPathHelper extends UrlPathHelper { }
public static class TestResourceCache extends ConcurrentMapCache {
public TestResourceCache(String name) {
super(name);
}
}
}

View File

@@ -30,7 +30,7 @@ import org.springframework.mock.web.test.MockServletContext;
import org.springframework.web.context.support.GenericWebApplicationContext;
import org.springframework.web.servlet.HandlerMapping;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
import org.springframework.web.servlet.resource.AppCacheManifestTransfomer;
import org.springframework.web.servlet.resource.AppCacheManifestTransformer;
import org.springframework.web.servlet.resource.CachingResourceResolver;
import org.springframework.web.servlet.resource.CachingResourceTransformer;
import org.springframework.web.servlet.resource.CssLinkResourceTransformer;
@@ -145,7 +145,7 @@ public class ResourceHandlerRegistryTests {
.addContentVersionStrategy("/**");
this.registration.resourceChain(true).addResolver(versionResolver)
.addTransformer(new AppCacheManifestTransfomer());
.addTransformer(new AppCacheManifestTransformer());
ResourceHttpRequestHandler handler = getHandler("/resources/**");
List<ResourceResolver> resolvers = handler.getResourceResolvers();
@@ -158,7 +158,7 @@ public class ResourceHandlerRegistryTests {
assertThat(transformers, Matchers.hasSize(3));
assertThat(transformers.get(0), Matchers.instanceOf(CachingResourceTransformer.class));
assertThat(transformers.get(1), Matchers.instanceOf(CssLinkResourceTransformer.class));
assertThat(transformers.get(2), Matchers.instanceOf(AppCacheManifestTransfomer.class));
assertThat(transformers.get(2), Matchers.instanceOf(AppCacheManifestTransformer.class));
}
@Test
@@ -167,7 +167,7 @@ public class ResourceHandlerRegistryTests {
VersionResourceResolver versionResolver = Mockito.mock(VersionResourceResolver.class);
PathResourceResolver pathResourceResolver = new PathResourceResolver();
CachingResourceTransformer cachingTransformer = Mockito.mock(CachingResourceTransformer.class);
AppCacheManifestTransfomer appCacheTransformer = Mockito.mock(AppCacheManifestTransfomer.class);
AppCacheManifestTransformer appCacheTransformer = Mockito.mock(AppCacheManifestTransformer.class);
CssLinkResourceTransformer cssLinkTransformer = new CssLinkResourceTransformer();
this.registration.setCachePeriod(3600)

View File

@@ -34,13 +34,13 @@ import static org.mockito.BDDMockito.*;
/**
* Unit tests for
* {@link AppCacheManifestTransfomer}.
* {@link AppCacheManifestTransformer}.
*
* @author Brian Clozel
*/
public class AppCacheManifestTransformerTests {
private AppCacheManifestTransfomer transformer;
private AppCacheManifestTransformer transformer;
private ResourceTransformerChain chain;
@@ -48,7 +48,7 @@ public class AppCacheManifestTransformerTests {
@Before
public void setup() {
this.transformer = new AppCacheManifestTransfomer();
this.transformer = new AppCacheManifestTransformer();
this.chain = mock(ResourceTransformerChain.class);
this.request = mock(HttpServletRequest.class);
}