diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java index 6bac90cd6c..3ec0b059fa 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ResourcesBeanDefinitionParser.java @@ -19,6 +19,9 @@ package org.springframework.web.servlet.config; import java.util.Arrays; import java.util.Map; +import org.springframework.web.servlet.handler.MappedInterceptor; +import org.springframework.web.servlet.resource.ResourceUrlProvider; +import org.springframework.web.servlet.resource.ResourceUrlProviderExposingInterceptor; import org.w3c.dom.Element; import org.springframework.beans.factory.config.BeanDefinition; @@ -71,11 +74,15 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser { private static final String CONTENT_VERSION_STRATEGY_ELEMENT = "content-version-strategy"; + private static final String RESOURCE_URL_PROVIDER = "mvcResourceUrlProvider"; + @Override public BeanDefinition parse(Element element, ParserContext parserContext) { Object source = parserContext.extractSource(element); + registerUrlProvider(parserContext, source); + String resourceHandlerName = registerResourceHandler(parserContext, element, source); if (resourceHandlerName == null) { return null; @@ -113,6 +120,28 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser { return null; } + private void registerUrlProvider(ParserContext parserContext, Object source) { + if (!parserContext.getRegistry().containsBeanDefinition(RESOURCE_URL_PROVIDER)) { + RootBeanDefinition urlProvider = new RootBeanDefinition(ResourceUrlProvider.class); + urlProvider.setSource(source); + urlProvider.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + parserContext.getRegistry().registerBeanDefinition(RESOURCE_URL_PROVIDER, urlProvider); + parserContext.registerComponent(new BeanComponentDefinition(urlProvider, RESOURCE_URL_PROVIDER)); + + RootBeanDefinition interceptor = new RootBeanDefinition(ResourceUrlProviderExposingInterceptor.class); + interceptor.setSource(source); + interceptor.getConstructorArgumentValues().addIndexedArgumentValue(0, urlProvider); + + RootBeanDefinition mappedInterceptor = new RootBeanDefinition(MappedInterceptor.class); + mappedInterceptor.setSource(source); + mappedInterceptor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + mappedInterceptor.getConstructorArgumentValues().addIndexedArgumentValue(0, (Object) null); + mappedInterceptor.getConstructorArgumentValues().addIndexedArgumentValue(1, interceptor); + String mappedInterceptorName = parserContext.getReaderContext().registerWithGeneratedName(mappedInterceptor); + parserContext.registerComponent(new BeanComponentDefinition(mappedInterceptor, mappedInterceptorName)); + } + } + private String registerResourceHandler(ParserContext parserContext, Element element, Object source) { String locationAttr = element.getAttribute("location"); if (!StringUtils.hasText(locationAttr)) { diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java index d7fbb7b07c..e2f7727dfe 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java @@ -269,7 +269,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv InterceptorRegistry registry = new InterceptorRegistry(); addInterceptors(registry); registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService())); - registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(resourceUrlPathTranslator())); + registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider())); this.interceptors = registry.getInterceptors(); } return this.interceptors.toArray(); @@ -387,17 +387,17 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv } @Bean - public ResourceUrlProvider resourceUrlPathTranslator() { - ResourceUrlProvider translator = new ResourceUrlProvider(); + public ResourceUrlProvider mvcResourceUrlProvider() { + ResourceUrlProvider urlProvider = new ResourceUrlProvider(); UrlPathHelper pathHelper = getPathMatchConfigurer().getUrlPathHelper(); if (pathHelper != null) { - translator.setUrlPathHelper(pathHelper); + urlProvider.setUrlPathHelper(pathHelper); } PathMatcher pathMatcher = getPathMatchConfigurer().getPathMatcher(); if (pathMatcher != null) { - translator.setPathMatcher(pathMatcher); + urlProvider.setPathMatcher(pathMatcher); } - return translator; + return urlProvider; } /** diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java index ab9024fba6..92523958b1 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java @@ -93,6 +93,8 @@ 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.ResourceUrlProvider; +import org.springframework.web.servlet.resource.ResourceUrlProviderExposingInterceptor; import org.springframework.web.servlet.resource.VersionResourceResolver; import org.springframework.web.servlet.theme.ThemeChangeInterceptor; import org.springframework.web.servlet.view.groovy.GroovyMarkupConfigurer; @@ -288,7 +290,7 @@ public class MvcNamespaceTests { @Test public void testResources() throws Exception { - loadBeanDefinitions("mvc-config-resources.xml", 7); + loadBeanDefinitions("mvc-config-resources.xml", 9); HttpRequestHandlerAdapter adapter = appContext.getBean(HttpRequestHandlerAdapter.class); assertNotNull(adapter); @@ -304,6 +306,13 @@ public class MvcNamespaceTests { assertNotNull(beanNameMapping); assertEquals(2, beanNameMapping.getOrder()); + ResourceUrlProvider urlProvider = appContext.getBean(ResourceUrlProvider.class); + assertNotNull(urlProvider); + + MappedInterceptor mappedInterceptor = appContext.getBean(MappedInterceptor.class); + assertNotNull(urlProvider); + assertEquals(ResourceUrlProviderExposingInterceptor.class, mappedInterceptor.getInterceptor().getClass()); + MockHttpServletRequest request = new MockHttpServletRequest(); request.setRequestURI("/resources/foo.css"); request.setMethod("GET"); @@ -321,7 +330,7 @@ public class MvcNamespaceTests { @Test public void testResourcesWithOptionalAttributes() throws Exception { - loadBeanDefinitions("mvc-config-resources-optional-attrs.xml", 7); + loadBeanDefinitions("mvc-config-resources-optional-attrs.xml", 9); SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class); assertNotNull(mapping); @@ -336,7 +345,7 @@ public class MvcNamespaceTests { @Test public void testResourcesWithResolversTransformers() throws Exception { - loadBeanDefinitions("mvc-config-resources-chain.xml", 8); + loadBeanDefinitions("mvc-config-resources-chain.xml", 10); SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class); assertNotNull(mapping); @@ -374,7 +383,7 @@ public class MvcNamespaceTests { @Test public void testResourcesWithResolversTransformersCustom() throws Exception { - loadBeanDefinitions("mvc-config-resources-chain-no-auto.xml", 9); + loadBeanDefinitions("mvc-config-resources-chain-no-auto.xml", 11); SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class); assertNotNull(mapping); @@ -743,7 +752,7 @@ public class MvcNamespaceTests { @Test public void testPathMatchingHandlerMappings() throws Exception { - loadBeanDefinitions("mvc-config-path-matching-mappings.xml", 20); + loadBeanDefinitions("mvc-config-path-matching-mappings.xml", 22); RequestMappingHandlerMapping requestMapping = appContext.getBean(RequestMappingHandlerMapping.class); assertNotNull(requestMapping);