From 62f2858f7f6da9eb84366b3c5f4f693838d159f3 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 13 Nov 2012 21:06:49 -0500 Subject: [PATCH] Fix issue with SpEL in mvc namespace This change ensures that the location attribute of a resource mapping and the path attribute of an interceptor mapping support SpEL expressions. Issue: SPR-9291, SPR-9848 --- .../InterceptorsBeanDefinitionParser.java | 11 +++---- .../config/ResourcesBeanDefinitionParser.java | 30 +++++++++++-------- 2 files changed, 23 insertions(+), 18 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/InterceptorsBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/InterceptorsBeanDefinitionParser.java index e0890ce750..167963844d 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/InterceptorsBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/InterceptorsBeanDefinitionParser.java @@ -21,6 +21,7 @@ import java.util.List; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.parsing.BeanComponentDefinition; import org.springframework.beans.factory.parsing.CompositeComponentDefinition; +import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; @@ -47,8 +48,8 @@ class InterceptorsBeanDefinitionParser implements BeanDefinitionParser { mappedInterceptorDef.setSource(parserContext.extractSource(interceptor)); mappedInterceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - String[] includePatterns = null; - String[] excludePatterns = null; + ManagedList includePatterns = null; + ManagedList excludePatterns = null; Object interceptorBean; if ("interceptor".equals(interceptor.getLocalName())) { includePatterns = getIncludePatterns(interceptor, "mapping"); @@ -71,11 +72,11 @@ class InterceptorsBeanDefinitionParser implements BeanDefinitionParser { return null; } - private String[] getIncludePatterns(Element interceptor, String elementName) { + private ManagedList getIncludePatterns(Element interceptor, String elementName) { List paths = DomUtils.getChildElementsByTagName(interceptor, elementName); - String[] patterns = new String[paths.size()]; + ManagedList patterns = new ManagedList(paths.size()); for (int i = 0; i < paths.size(); i++) { - patterns[i] = paths.get(i).getAttribute("path"); + patterns.add(paths.get(i).getAttribute("path")); } return patterns; } 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 f2f05204c3..fa44b4628a 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 @@ -22,6 +22,7 @@ import org.w3c.dom.Element; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.parsing.BeanComponentDefinition; +import org.springframework.beans.factory.support.ManagedList; import org.springframework.beans.factory.support.ManagedMap; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; @@ -35,8 +36,8 @@ import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; /** * {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses a * {@code resources} element to register a {@link ResourceHttpRequestHandler}. - * Will also register a {@link SimpleUrlHandlerMapping} for mapping resource requests, - * and a {@link HttpRequestHandlerAdapter}. + * Will also register a {@link SimpleUrlHandlerMapping} for mapping resource requests, + * and a {@link HttpRequestHandlerAdapter}. * * @author Keith Donald * @author Jeremy Grelle @@ -46,12 +47,12 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser { public BeanDefinition parse(Element element, ParserContext parserContext) { Object source = parserContext.extractSource(element); - + String resourceHandlerName = registerResourceHandler(parserContext, element, source); if (resourceHandlerName == null) { return null; } - + Map urlMap = new ManagedMap(); String resourceRequestPath = element.getAttribute("mapping"); if (!StringUtils.hasText(resourceRequestPath)) { @@ -59,38 +60,41 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser { return null; } urlMap.put(resourceRequestPath, resourceHandlerName); - + RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class); handlerMappingDef.setSource(source); handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); handlerMappingDef.getPropertyValues().add("urlMap", urlMap); - + String order = element.getAttribute("order"); // use a default of near-lowest precedence, still allowing for even lower precedence in other mappings handlerMappingDef.getPropertyValues().add("order", StringUtils.hasText(order) ? order : Ordered.LOWEST_PRECEDENCE - 1); - + String beanName = parserContext.getReaderContext().generateBeanName(handlerMappingDef); parserContext.getRegistry().registerBeanDefinition(beanName, handlerMappingDef); - parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, beanName)); + parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, beanName)); - // Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off" + // Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off" // Register HttpRequestHandlerAdapter MvcNamespaceUtils.registerDefaultComponents(parserContext, source); return null; } - + private String registerResourceHandler(ParserContext parserContext, Element element, Object source) { String locationAttr = element.getAttribute("location"); if (!StringUtils.hasText(locationAttr)) { parserContext.getReaderContext().error("The 'location' attribute is required.", parserContext.extractSource(element)); return null; - } + } + + ManagedList locations = new ManagedList(); + locations.addAll(StringUtils.commaDelimitedListToSet(locationAttr)); RootBeanDefinition resourceHandlerDef = new RootBeanDefinition(ResourceHttpRequestHandler.class); resourceHandlerDef.setSource(source); resourceHandlerDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - resourceHandlerDef.getPropertyValues().add("locations", StringUtils.commaDelimitedListToStringArray(locationAttr)); + resourceHandlerDef.getPropertyValues().add("locations", locations); String cacheSeconds = element.getAttribute("cache-period"); if (StringUtils.hasText(cacheSeconds)) { @@ -99,7 +103,7 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser { String beanName = parserContext.getReaderContext().generateBeanName(resourceHandlerDef); parserContext.getRegistry().registerBeanDefinition(beanName, resourceHandlerDef); - parserContext.registerComponent(new BeanComponentDefinition(resourceHandlerDef, beanName)); + parserContext.registerComponent(new BeanComponentDefinition(resourceHandlerDef, beanName)); return beanName; }