From 5e1a5c8d5182e04acd35ebeb5dee098104439c1d Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Sat, 12 Jul 2014 22:19:18 -0400 Subject: [PATCH] Update view-resolver namespace Issue: SPR-7093 --- .../AnnotationDrivenBeanDefinitionParser.java | 5 +- .../FreeMarkerBeanDefinitionParser.java | 66 ++++ .../servlet/config/MvcNamespaceHandler.java | 5 +- .../web/servlet/config/MvcNamespaceUtils.java | 1 + .../config/TilesBeanDefinitionParser.java | 75 +++++ .../config/VelocityBeanDefinitionParser.java | 58 ++++ .../ViewResolutionBeanDefinitionParser.java | 252 --------------- .../ViewResolversBeanDefinitionParser.java | 189 +++++++++++ .../view/ContentNegotiatingViewResolver.java | 7 + .../web/servlet/config/spring-mvc-4.1.xsd | 304 ++++++++++-------- .../web/servlet/config/MvcNamespaceTests.java | 152 +++++---- ...ontent-negotiating-with-default-values.xml | 26 -- .../config/mvc-config-content-negotiating.xml | 53 --- ...mvc-config-content-negotiation-manager.xml | 8 +- ...ig-view-resolution-content-negotiation.xml | 41 +++ .../config/mvc-config-view-resolution.xml | 38 ++- 16 files changed, 717 insertions(+), 563 deletions(-) create mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/config/FreeMarkerBeanDefinitionParser.java create mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/config/TilesBeanDefinitionParser.java create mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/config/VelocityBeanDefinitionParser.java delete mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolutionBeanDefinitionParser.java create mode 100644 spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java delete mode 100644 spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating-with-default-values.xml delete mode 100644 spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating.xml create mode 100644 spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution-content-negotiation.xml diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java index fa26e45a0ec..deb753e70b1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParser.java @@ -146,9 +146,10 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv */ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { + public static final String CONTENT_NEGOTIATION_MANAGER_BEAN_NAME = "mvcContentNegotiationManager"; + private static final boolean javaxValidationPresent = ClassUtils.isPresent( "javax.validation.Validator", AnnotationDrivenBeanDefinitionParser.class.getClassLoader()); - private static boolean romePresent = ClassUtils.isPresent("com.rometools.rome.feed.WireFeed", AnnotationDrivenBeanDefinitionParser.class.getClassLoader()); @@ -354,7 +355,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser { factoryBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); factoryBeanDef.getPropertyValues().add("mediaTypes", getDefaultMediaTypes()); - String beanName = "mvcContentNegotiationManager"; + String beanName = CONTENT_NEGOTIATION_MANAGER_BEAN_NAME; parserContext.getReaderContext().getRegistry().registerBeanDefinition(beanName , factoryBeanDef); parserContext.registerComponent(new BeanComponentDefinition(factoryBeanDef, beanName)); contentNegotiationManagerRef = new RuntimeBeanReference(beanName); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/FreeMarkerBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/FreeMarkerBeanDefinitionParser.java new file mode 100644 index 00000000000..63e801ffe40 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/FreeMarkerBeanDefinitionParser.java @@ -0,0 +1,66 @@ +/* + * Copyright 2002-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.servlet.config; + +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Element; + +import java.util.ArrayList; +import java.util.List; + +/** + * Parse the MVC namespace element and register + * FreeMarkerConfigurer bean + * + * @author Rossen Stoyanchev + * @since 4.1 + */ +public class FreeMarkerBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { + + public static final String BEAN_NAME = "mvcFreeMarkerConfigurer"; + + + @Override + protected String getBeanClassName(Element element) { + return "org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"; + } + + @Override + protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) { + return BEAN_NAME; + } + + @Override + protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + List childElements = DomUtils.getChildElementsByTagName(element, "template-loader-path"); + if (!childElements.isEmpty()) { + List locations = new ArrayList(childElements.size()); + for (Element childElement : childElements) { + locations.add(childElement.getAttribute("location")); + } + if (locations.isEmpty()) { + locations.add("/WEB-INF/"); + } + builder.addPropertyValue("templateLoaderPaths", locations.toArray(new String[locations.size()])); + } + } + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java index 1f7d81d2866..b78951fbd78 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java @@ -35,7 +35,10 @@ public class MvcNamespaceHandler extends NamespaceHandlerSupport { registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser()); registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser()); registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser()); - registerBeanDefinitionParser("view-resolution", new ViewResolutionBeanDefinitionParser()); + registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser()); + registerBeanDefinitionParser("tiles", new TilesBeanDefinitionParser()); + registerBeanDefinitionParser("freemarker", new FreeMarkerBeanDefinitionParser()); + registerBeanDefinitionParser("velocity", new VelocityBeanDefinitionParser()); } } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java index e6c426c1cff..2e62d944234 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceUtils.java @@ -50,6 +50,7 @@ abstract class MvcNamespaceUtils { private static final String PATH_MATCHER_BEAN_NAME = "mvcPathMatcher"; + public static void registerDefaultComponents(ParserContext parserContext, Object source) { registerBeanNameUrlHandlerMapping(parserContext, source); registerHttpRequestHandlerAdapter(parserContext, source); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/TilesBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/TilesBeanDefinitionParser.java new file mode 100644 index 00000000000..358ac823856 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/TilesBeanDefinitionParser.java @@ -0,0 +1,75 @@ +/* + * Copyright 2002-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.servlet.config; + +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Element; + +import java.util.ArrayList; +import java.util.List; + +/** + * Parse the MVC namespace element and register + * TilesConfigurer bean + + * @author Rossen Stoyanchev + * @since 4.1 + */ +public class TilesBeanDefinitionParser extends AbstractSingleBeanDefinitionParser { + + public static final String BEAN_NAME = "mvcTilesConfigurer"; + + + @Override + protected String getBeanClassName(Element element) { + return "org.springframework.web.servlet.view.tiles3.TilesConfigurer"; + } + + @Override + protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) { + return BEAN_NAME; + } + + @Override + protected boolean shouldGenerateId() { + return super.shouldGenerateId(); + } + + @Override + protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + List childElements = DomUtils.getChildElementsByTagName(element, "definitions"); + if (!childElements.isEmpty()) { + List locations = new ArrayList(childElements.size()); + for (Element childElement : childElements) { + locations.add(childElement.getAttribute("location")); + } + builder.addPropertyValue("definitions", locations.toArray(new String[locations.size()])); + } + if (element.hasAttribute("check-refresh")) { + builder.addPropertyValue("checkRefresh", element.getAttribute("check-refresh")); + } + if (element.hasAttribute("validate-definitions")) { + builder.addPropertyValue("validateDefinitions", element.getAttribute("validate-definitions")); + } + } + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/VelocityBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/VelocityBeanDefinitionParser.java new file mode 100644 index 00000000000..f036f12a03d --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/VelocityBeanDefinitionParser.java @@ -0,0 +1,58 @@ +/* + * Copyright 2002-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.servlet.config; + +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.w3c.dom.Element; + + +/** + * Parse the MVC namespace element and register an + * VelocityConfigurer bean + * + * @author Rossen Stoyanchev + * @since 4.1 + */ +public class VelocityBeanDefinitionParser extends AbstractSimpleBeanDefinitionParser { + + public static final String BEAN_NAME = "mvcVelocityConfigurer"; + + @Override + protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) { + return BEAN_NAME; + } + + @Override + protected String getBeanClassName(Element element) { + return "org.springframework.web.servlet.view.velocity.VelocityConfigurer"; + } + + @Override + protected boolean isEligibleAttribute(String attributeName) { + return attributeName.equals("resource-loader-path"); + } + + @Override + protected void postProcess(BeanDefinitionBuilder builder, Element element) { + if (!builder.getBeanDefinition().hasAttribute("resourceLoaderPath")) { + builder.getBeanDefinition().setAttribute("resourceLoaderPath", "/WEB-INF/"); + } + } +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolutionBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolutionBeanDefinitionParser.java deleted file mode 100644 index 12234e13f56..00000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolutionBeanDefinitionParser.java +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright 2002-2014 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. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.web.servlet.config; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.beans.factory.config.BeanDefinition; -import org.springframework.beans.factory.config.RuntimeBeanReference; -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; -import org.springframework.util.StringUtils; -import org.springframework.util.xml.DomUtils; -import org.springframework.web.servlet.view.BeanNameViewResolver; -import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; -import org.springframework.web.servlet.view.InternalResourceViewResolver; -import org.springframework.web.servlet.ViewResolver; - -import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; -import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; -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 org.w3c.dom.Element; - -/** - * {@link org.springframework.beans.factory.xml.BeanDefinitionParser} that parses a - * {@code view-resolution} element to register a set of {@link ViewResolver} definitions. - * - * @author Sivaprasad Valluru - * @author Sebastien Deleuze - * @since 4.1 - */ -public class ViewResolutionBeanDefinitionParser implements BeanDefinitionParser { - - private Object source; - - public BeanDefinition parse(Element element, ParserContext parserContext) { - - source= parserContext.extractSource(element); - CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(),source); - parserContext.pushContainingComponent(compDefinition); - - List viewResolverElements = - DomUtils.getChildElementsByTagName(element, new String[] { "jsp", "tiles", "bean-name", "freemarker", "velocity", "bean", "ref" }); - ManagedList viewResolvers = new ManagedList(); - viewResolvers.setSource(parserContext.extractSource(element)); - int order = 0; - - for (Element viewResolverElement : viewResolverElements) { - if ("jsp".equals(viewResolverElement.getLocalName())) { - viewResolvers.add(registerInternalResourceViewResolverBean(viewResolverElement, parserContext, order)); - } - if("bean-name".equals(viewResolverElement.getLocalName())){ - viewResolvers.add(registerBeanNameViewResolverBean(viewResolverElement, parserContext, order)); - } - if ("tiles".equals(viewResolverElement.getLocalName())) { - viewResolvers.add(registerTilesViewResolverBean(viewResolverElement, parserContext, order)); - registerTilesConfigurerBean(viewResolverElement, parserContext); - } - if("freemarker".equals(viewResolverElement.getLocalName())){ - viewResolvers.add(registerFreemarkerViewResolverBean(viewResolverElement, parserContext, order)); - registerFreemarkerConfigurerBean(viewResolverElement, parserContext); - } - if("velocity".equals(viewResolverElement.getLocalName())){ - viewResolvers.add(registerVelocityViewResolverBean(viewResolverElement, parserContext, order)); - registerVelocityConfigurerBean(viewResolverElement, parserContext); - } - if("bean".equals(viewResolverElement.getLocalName()) || "ref".equals(viewResolverElement.getLocalName())){ - viewResolvers.add(parserContext.getDelegate().parsePropertySubElement(viewResolverElement, null)); - } - - order++; - } - viewResolverElements = DomUtils.getChildElementsByTagName(element, new String[] { "content-negotiating" }); - if(!viewResolverElements.isEmpty()) { - registerContentNegotiatingViewResolverBean(viewResolverElements.get(0), parserContext, viewResolvers); - } - - parserContext.popAndRegisterContainingComponent(); - return null; - } - - - private BeanDefinition registerBean(Map propertyMap,Class beanClass, ParserContext parserContext ){ - RootBeanDefinition beanDef = new RootBeanDefinition(beanClass); - beanDef.setSource(source); - beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); - - for(String propertyName:propertyMap.keySet()){ - beanDef.getPropertyValues().add(propertyName, propertyMap.get(propertyName)); - } - String beanName = parserContext.getReaderContext().generateBeanName(beanDef); - parserContext.getRegistry().registerBeanDefinition(beanName, beanDef); - parserContext.registerComponent(new BeanComponentDefinition(beanDef, beanName)); - return beanDef; - } - - private BeanDefinition registerContentNegotiatingViewResolverBean(Element viewResolverElement, ParserContext parserContext, ManagedList viewResolvers) { - Map propertyMap = new HashMap(); - ManagedList defaultViewBeanDefinitions = new ManagedList(); - List defaultViewElements = - DomUtils.getChildElementsByTagName(viewResolverElement, new String[] { "default-views" }); - if(!defaultViewElements.isEmpty()) { - for(Element beanElem : DomUtils.getChildElementsByTagName(defaultViewElements.get(0), "bean", "ref")) { - defaultViewBeanDefinitions.add(parserContext.getDelegate().parsePropertySubElement(beanElem, null)); - } - } - if(viewResolverElement.hasAttribute("use-not-acceptable")) { - propertyMap.put("useNotAcceptableStatusCode", viewResolverElement.getAttribute("use-not-acceptable")); - } - if(viewResolverElement.hasAttribute("manager")) { - propertyMap.put("contentNegotiationManager", new RuntimeBeanReference(viewResolverElement.getAttribute("manager"))); - } else { - propertyMap.put("contentNegotiationManager", new RuntimeBeanReference("mvcContentNegotiationManager")); - } - if(viewResolvers != null && !viewResolvers.isEmpty()) { - propertyMap.put("viewResolvers", viewResolvers); - } - if(defaultViewBeanDefinitions != null && !defaultViewBeanDefinitions.isEmpty()) { - propertyMap.put("defaultViews", defaultViewBeanDefinitions); - } - return registerBean(propertyMap, ContentNegotiatingViewResolver.class, parserContext); - } - - private BeanDefinition registerFreemarkerConfigurerBean(Element viewResolverElement, ParserContext parserContext) { - Map propertyMap = new HashMap(); - if(viewResolverElement.hasAttribute("template-loader-paths")) { - String[] paths = StringUtils.commaDelimitedListToStringArray(viewResolverElement.getAttribute("template-loader-paths")); - propertyMap.put("templateLoaderPaths", paths); - } else { - propertyMap.put("templateLoaderPaths", new String[]{"/WEB-INF/"}); - } - return registerBean(propertyMap, FreeMarkerConfigurer.class, parserContext); - } - - private BeanDefinition registerFreemarkerViewResolverBean(Element viewResolverElement, ParserContext parserContext, int order) { - Map propertyMap = new HashMap(); - if(viewResolverElement.hasAttribute("prefix")) { - propertyMap.put("prefix", viewResolverElement.getAttribute("prefix")); - } - if(viewResolverElement.hasAttribute("suffix")) { - propertyMap.put("suffix", viewResolverElement.getAttribute("suffix")); - } - else { - propertyMap.put("suffix", ".ftl"); - } - if(viewResolverElement.hasAttribute("cache")) { - propertyMap.put("cache", viewResolverElement.getAttribute("cache")); - } - propertyMap.put("order", order); - return registerBean(propertyMap, FreeMarkerViewResolver.class, parserContext); - } - - private BeanDefinition registerVelocityConfigurerBean(Element viewResolverElement, ParserContext parserContext) { - String resourceLoaderPath = viewResolverElement.getAttribute("resource-loader-path"); - Map propertyMap = new HashMap(); - if(viewResolverElement.hasAttribute("resource-loader-path")) { - propertyMap.put("resourceLoaderPath", resourceLoaderPath); - } else { - propertyMap.put("resourceLoaderPath", "/WEB-INF/"); - } - return registerBean(propertyMap, VelocityConfigurer.class, parserContext); - } - - private BeanDefinition registerVelocityViewResolverBean(Element viewResolverElement, ParserContext parserContext, int order) { - Map propertyMap = new HashMap(); - if(viewResolverElement.hasAttribute("prefix")) { - propertyMap.put("prefix", viewResolverElement.getAttribute("prefix")); - } - if(viewResolverElement.hasAttribute("suffix")) { - propertyMap.put("suffix", viewResolverElement.getAttribute("suffix")); - } - else { - propertyMap.put("suffix", ".vm"); - } - if(viewResolverElement.hasAttribute("cache")) { - propertyMap.put("cache", viewResolverElement.getAttribute("cache")); - } - propertyMap.put("order", order); - return registerBean(propertyMap, VelocityViewResolver.class, parserContext); - } - - private BeanDefinition registerBeanNameViewResolverBean(Element viewResolverElement, ParserContext parserContext, int order) { - Map propertyMap = new HashMap(); - propertyMap.put("order", order); - return registerBean(propertyMap, BeanNameViewResolver.class, parserContext); - } - - private BeanDefinition registerTilesConfigurerBean(Element viewResolverElement, ParserContext parserContext) { - Map propertyMap = new HashMap(); - if(viewResolverElement.hasAttribute("definitions")) { - String[] definitions = StringUtils.commaDelimitedListToStringArray(viewResolverElement.getAttribute("definitions")); - propertyMap.put("definitions", definitions); - } - if(viewResolverElement.hasAttribute("check-refresh")) { - propertyMap.put("checkRefresh", viewResolverElement.getAttribute("check-refresh")); - } - return registerBean(propertyMap, TilesConfigurer.class, parserContext); - } - - private BeanDefinition registerTilesViewResolverBean(Element viewResolverElement, ParserContext parserContext, int order) { - Map propertyMap = new HashMap(); - if(viewResolverElement.hasAttribute("prefix")) { - propertyMap.put("prefix", viewResolverElement.getAttribute("prefix")); - } - if(viewResolverElement.hasAttribute("suffix")) { - propertyMap.put("suffix", viewResolverElement.getAttribute("suffix")); - } - propertyMap.put("order", order); - return registerBean(propertyMap, TilesViewResolver.class, parserContext); - } - - private BeanDefinition registerInternalResourceViewResolverBean(Element viewResolverElement, ParserContext parserContext, int order) { - Map propertyMap = new HashMap(); - if(viewResolverElement.hasAttribute("prefix")) { - propertyMap.put("prefix", viewResolverElement.getAttribute("prefix")); - } - else { - propertyMap.put("prefix", "/WEB-INF/"); - } - if(viewResolverElement.hasAttribute("suffix")) { - propertyMap.put("suffix", viewResolverElement.getAttribute("suffix")); - } - else { - propertyMap.put("suffix", ".jsp"); - } - propertyMap.put("order", order); - return registerBean(propertyMap, InternalResourceViewResolver.class, parserContext); - } - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java new file mode 100644 index 00000000000..5cf24777070 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java @@ -0,0 +1,189 @@ +/* + * Copyright 2002-2014 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. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.web.servlet.config; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.springframework.beans.MutablePropertyValues; +import org.springframework.beans.factory.config.BeanDefinition; +import org.springframework.beans.factory.config.RuntimeBeanReference; +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; +import org.springframework.core.Ordered; +import org.springframework.util.xml.DomUtils; +import org.springframework.web.servlet.view.BeanNameViewResolver; +import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; +import org.springframework.web.servlet.view.InternalResourceViewResolver; + +import org.springframework.web.servlet.view.ViewResolverComposite; +import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver; +import org.springframework.web.servlet.view.tiles3.TilesViewResolver; +import org.springframework.web.servlet.view.velocity.VelocityViewResolver; +import org.w3c.dom.Element; + +/** + * Parse the {@code view-resolvers} MVC namespace element and register + * {@link org.springframework.web.servlet.ViewResolver} bean definitions. + * + *

All registered resolvers are wrapped in a single (composite) ViewResolver + * with its order property set to 0 so that other external resolvers may be ordered + * before or after it. + * + *

When content negotiation is enabled the order property is set to highest priority + * instead with the ContentNeogitatingViewResolver encapsulating all other registered + * view resolver instances. That way the resolvers registered through the MVC namespace + * form self-encapsulated resolver chain. + * + * @author Sivaprasad Valluru + * @author Sebastien Deleuze + * @author Rossen Stoyanchev + * @since 4.1 + * @see org.springframework.web.servlet.config.TilesBeanDefinitionParser + * @see org.springframework.web.servlet.config.FreeMarkerBeanDefinitionParser + * @see org.springframework.web.servlet.config.VelocityBeanDefinitionParser + */ +public class ViewResolversBeanDefinitionParser implements BeanDefinitionParser { + + public static final String VIEW_RESOLVER_BEAN_NAME = "mvcViewResolver"; + + + public BeanDefinition parse(Element element, ParserContext context) { + Object source = context.extractSource(element); + context.pushContainingComponent(new CompositeComponentDefinition(element.getTagName(), source)); + + RootBeanDefinition compositeResolverBeanDef = new RootBeanDefinition(ViewResolverComposite.class); + compositeResolverBeanDef.setSource(source); + compositeResolverBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + + ManagedList resolvers = new ManagedList(4); + resolvers.setSource(context.extractSource(element)); + String[] names = new String[] {"jsp", "tiles", "bean-name", "freemarker", "velocity", "bean", "ref"}; + + for (Element resolverElement : DomUtils.getChildElementsByTagName(element, names)) { + String name = resolverElement.getLocalName(); + if ("bean".equals(name) || "ref".equals(name)) { + resolvers.add(context.getDelegate().parsePropertySubElement(resolverElement, null)); + continue; + } + RootBeanDefinition resolverBeanDef = null; + if ("jsp".equals(name)) { + resolverBeanDef = new RootBeanDefinition(InternalResourceViewResolver.class); + resolverBeanDef.getPropertyValues().add("prefix", "/WEB-INF/"); + resolverBeanDef.getPropertyValues().add("suffix", ".jsp"); + addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef); + } + else if ("tiles".equals(name)) { + resolverBeanDef = new RootBeanDefinition(TilesViewResolver.class); + addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef); + } + else if ("freemarker".equals(name)) { + resolverBeanDef = new RootBeanDefinition(FreeMarkerViewResolver.class); + resolverBeanDef.getPropertyValues().add("suffix", ".ftl"); + addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef); + } + else if ("velocity".equals(name)) { + resolverBeanDef = new RootBeanDefinition(VelocityViewResolver.class); + resolverBeanDef.getPropertyValues().add("suffix", ".vm"); + addUrlBasedViewResolverProperties(resolverElement, resolverBeanDef); + } + else if ("bean-name".equals(name)) { + resolverBeanDef = new RootBeanDefinition(BeanNameViewResolver.class); + } + else { + // Should never happen + throw new IllegalStateException("Unexpected element name: " + name); + } + resolverBeanDef.setSource(source); + resolverBeanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + resolvers.add(resolverBeanDef); + } + + List elementList = DomUtils.getChildElementsByTagName(element, new String[] {"content-negotiation"}); + if (elementList.isEmpty()) { + compositeResolverBeanDef.getPropertyValues().add("order", 0); + compositeResolverBeanDef.getPropertyValues().add("viewResolvers", resolvers); + } + else if (elementList.size() == 1) { + BeanDefinition beanDef = createContentNegotiatingViewResolver(elementList.get(0), context); + beanDef.getPropertyValues().add("viewResolvers", resolvers); + ManagedList list = new ManagedList(1); + list.add(beanDef); + + compositeResolverBeanDef.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE); + compositeResolverBeanDef.getPropertyValues().add("viewResolvers", list); + } + else if (elementList.size() > 1) { + throw new IllegalArgumentException("Only one element is allowed."); + } + + String beanName = VIEW_RESOLVER_BEAN_NAME; + context.getReaderContext().getRegistry().registerBeanDefinition(beanName, compositeResolverBeanDef); + context.registerComponent(new BeanComponentDefinition(compositeResolverBeanDef, beanName)); + + context.popAndRegisterContainingComponent(); + return null; + } + + private void addUrlBasedViewResolverProperties(Element element, RootBeanDefinition beanDefinition) { + if (element.hasAttribute("prefix")) { + beanDefinition.getPropertyValues().add("prefix", element.getAttribute("prefix")); + } + if (element.hasAttribute("suffix")) { + beanDefinition.getPropertyValues().add("suffix", element.getAttribute("suffix")); + } + if (element.hasAttribute("cache-views")) { + beanDefinition.getPropertyValues().add("cache", element.getAttribute("cache-views")); + } + if (element.hasAttribute("view-class")) { + beanDefinition.getPropertyValues().add("viewClass", element.getAttribute("view-class")); + } + if (element.hasAttribute("view-names")) { + beanDefinition.getPropertyValues().add("viewNames", element.getAttribute("view-names")); + } + } + + private BeanDefinition createContentNegotiatingViewResolver(Element resolverElement, ParserContext context) { + RootBeanDefinition beanDef = new RootBeanDefinition(ContentNegotiatingViewResolver.class); + beanDef.setSource(context.extractSource(resolverElement)); + beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE); + MutablePropertyValues values = beanDef.getPropertyValues(); + + List elements = DomUtils.getChildElementsByTagName(resolverElement, new String[] {"default-views"}); + if (!elements.isEmpty()) { + ManagedList list = new ManagedList(); + for(Element element : DomUtils.getChildElementsByTagName(elements.get(0), "bean", "ref")) { + list.add(context.getDelegate().parsePropertySubElement(element, null)); + } + values.add("defaultViews", list); + } + if (resolverElement.hasAttribute("use-not-acceptable")) { + values.add("useNotAcceptableStatusCode", resolverElement.getAttribute("use-not-acceptable")); + } + String beanName = AnnotationDrivenBeanDefinitionParser.CONTENT_NEGOTIATION_MANAGER_BEAN_NAME; + if (context.getRegistry().containsBeanDefinition(beanName)) { + values.add("contentNegotiationManager", new RuntimeBeanReference(beanName)); + } + return beanDef; + } + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java index 6a1aef469b5..c3dd93694e9 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/view/ContentNegotiatingViewResolver.java @@ -220,6 +220,13 @@ public class ContentNegotiatingViewResolver extends WebApplicationObjectSupport this.useNotAcceptableStatusCode = useNotAcceptableStatusCode; } + /** + * Whether to return HTTP Status 406 if no suitable is found. + */ + public boolean isUseNotAcceptableStatusCode() { + return this.useNotAcceptableStatusCode; + } + /** * Set the default views to use when a more specific view can not be obtained * from the {@link ViewResolver} chain. diff --git a/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.1.xsd b/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.1.xsd index be2cc1cacf7..1d674d983a4 100644 --- a/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.1.xsd +++ b/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.1.xsd @@ -598,221 +598,259 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - + - - - - - - - - - - - - - - - - - - - + - + + + + + + - + - + - - - - - + + + - - - + + + - + element + or declare a TilesConfigurer bean. ]]> - + + Register a FreeMarkerViewResolver. + By default ".ftl" is configured as a view name suffix. + To configure FreeMarker you must also add a top-level element + or declare a FreeMarkerConfigurer bean. + ]]> - + element. + or declare a VelocityConfigurer bean. ]]> - + + Register a BeanNameViewResolver bean. + ]]> - - + - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + - - - - - + + + + + + + - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 7b11724d078..eda0a2ccd54 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 @@ -67,6 +67,7 @@ import org.springframework.web.method.support.InvocableHandlerMethod; import org.springframework.web.servlet.HandlerExecutionChain; import org.springframework.web.servlet.HandlerInterceptor; import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.handler.*; import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter; @@ -95,6 +96,8 @@ import org.springframework.web.servlet.view.velocity.VelocityViewResolver; import static org.junit.Assert.*; /** + * Tests loading actual MVC namespace configuration. + * * @author Keith Donald * @author Arjen Poutsma * @author Jeremy Grelle @@ -557,95 +560,87 @@ public class MvcNamespaceTests { } @Test - public void testViewResolvers() throws Exception { - loadBeanDefinitions("mvc-config-view-resolution.xml", 8); - - InternalResourceViewResolver internalResourceViewResolver = appContext.getBean(InternalResourceViewResolver.class); - assertNotNull(internalResourceViewResolver); - assertEquals(0, internalResourceViewResolver.getOrder()); - DirectFieldAccessor internalResourceViewResolverFieldAccessor = new DirectFieldAccessor(internalResourceViewResolver); - assertEquals("/WEB-INF/", internalResourceViewResolverFieldAccessor.getPropertyValue("prefix")); - assertEquals(".jsp", internalResourceViewResolverFieldAccessor.getPropertyValue("suffix")); - - BeanNameViewResolver beanNameViewResolver = appContext.getBean(BeanNameViewResolver.class); - assertNotNull(beanNameViewResolver); - assertEquals(1, beanNameViewResolver.getOrder()); - + public void testViewResolution() throws Exception { + loadBeanDefinitions("mvc-config-view-resolution.xml", 5); + + ViewResolverComposite compositeResolver = this.appContext.getBean(ViewResolverComposite.class); + assertNotNull(compositeResolver); + assertEquals(7, compositeResolver.getViewResolvers().size()); + assertEquals(0, compositeResolver.getOrder()); + + List resolvers = compositeResolver.getViewResolvers(); + assertEquals(BeanNameViewResolver.class, resolvers.get(0).getClass()); + + ViewResolver resolver = resolvers.get(1); + assertEquals(InternalResourceViewResolver.class, resolver.getClass()); + DirectFieldAccessor accessor = new DirectFieldAccessor(resolver); + assertEquals(InternalResourceView.class, accessor.getPropertyValue("viewClass")); + + assertEquals(TilesViewResolver.class, resolvers.get(2).getClass()); + + resolver = resolvers.get(3); + FreeMarkerViewResolver freeMarkerViewResolver = (FreeMarkerViewResolver) resolver; + accessor = new DirectFieldAccessor(resolver); + assertEquals("freemarker-", accessor.getPropertyValue("prefix")); + assertEquals(".freemarker", accessor.getPropertyValue("suffix")); + assertArrayEquals(new String[] {"my*", "*Report"}, (String[]) accessor.getPropertyValue("viewNames")); + assertEquals(1024, accessor.getPropertyValue("cacheLimit")); + + resolver = resolvers.get(4); + VelocityViewResolver velocityViewResolver = (VelocityViewResolver) resolver; + accessor = new DirectFieldAccessor(resolver); + assertEquals("", accessor.getPropertyValue("prefix")); + assertEquals(".vm", accessor.getPropertyValue("suffix")); + assertEquals(0, accessor.getPropertyValue("cacheLimit")); + + assertEquals(InternalResourceViewResolver.class, resolvers.get(5).getClass()); + assertEquals(InternalResourceViewResolver.class, resolvers.get(6).getClass()); + + TilesConfigurer tilesConfigurer = appContext.getBean(TilesConfigurer.class); assertNotNull(tilesConfigurer); - DirectFieldAccessor tilesConfigurerFieldAccessor = new DirectFieldAccessor(tilesConfigurer); - assertArrayEquals(new String[]{"/org/springframework/web/servlet/resource/tiles/tiles1.xml","/org/springframework/web/servlet/resource/tiles/tiles2.xml"}, - (String[])tilesConfigurerFieldAccessor.getPropertyValue("definitions")); - assertTrue((boolean)tilesConfigurerFieldAccessor.getPropertyValue("checkRefresh")); - - TilesViewResolver tilesViewResolver = appContext.getBean(TilesViewResolver.class); - assertNotNull(tilesViewResolver); - assertEquals(2, tilesViewResolver.getOrder()); - + String[] definitions = { + "/org/springframework/web/servlet/resource/tiles/tiles1.xml", + "/org/springframework/web/servlet/resource/tiles/tiles2.xml" + }; + accessor = new DirectFieldAccessor(tilesConfigurer); + assertArrayEquals(definitions, (String[]) accessor.getPropertyValue("definitions")); + assertTrue((boolean)accessor.getPropertyValue("checkRefresh")); + FreeMarkerConfigurer freeMarkerConfigurer = appContext.getBean(FreeMarkerConfigurer.class); assertNotNull(freeMarkerConfigurer); - DirectFieldAccessor freeMarkerConfigurerFieldAccessor = new DirectFieldAccessor(freeMarkerConfigurer); - assertArrayEquals(new String[]{"/","/test"}, - (String[])freeMarkerConfigurerFieldAccessor.getPropertyValue("templateLoaderPaths")); - - FreeMarkerViewResolver freeMarkerViewResolver = appContext.getBean(FreeMarkerViewResolver.class); - assertNotNull(freeMarkerViewResolver); - assertEquals(3, freeMarkerViewResolver.getOrder()); - DirectFieldAccessor freeMarkerViewResolverFieldAccessor = new DirectFieldAccessor(freeMarkerViewResolver); - assertEquals("", freeMarkerViewResolverFieldAccessor.getPropertyValue("prefix")); - assertEquals(".ftl", freeMarkerViewResolverFieldAccessor.getPropertyValue("suffix")); - assertEquals(0, freeMarkerViewResolverFieldAccessor.getPropertyValue("cacheLimit")); + accessor = new DirectFieldAccessor(freeMarkerConfigurer); + assertArrayEquals(new String[]{"/", "/test"}, (String[]) accessor.getPropertyValue("templateLoaderPaths")); VelocityConfigurer velocityConfigurer = appContext.getBean(VelocityConfigurer.class); assertNotNull(velocityConfigurer); - DirectFieldAccessor velocityConfigurerFieldAccessor = new DirectFieldAccessor(velocityConfigurer); - assertEquals("/", velocityConfigurerFieldAccessor.getPropertyValue("resourceLoaderPath")); - - VelocityViewResolver velocityViewResolver = appContext.getBean(VelocityViewResolver.class); - assertNotNull(velocityViewResolver); - assertEquals(4, velocityViewResolver.getOrder()); - DirectFieldAccessor velocityViewResolverFieldAccessor = new DirectFieldAccessor(velocityViewResolver); - assertEquals("", velocityViewResolverFieldAccessor.getPropertyValue("prefix")); - assertEquals(".vm", velocityViewResolverFieldAccessor.getPropertyValue("suffix")); - assertEquals(0, velocityViewResolverFieldAccessor.getPropertyValue("cacheLimit")); + accessor = new DirectFieldAccessor(velocityConfigurer); + assertEquals("/test", accessor.getPropertyValue("resourceLoaderPath")); } @Test - public void testContentNegotiating() throws Exception { - loadBeanDefinitions("mvc-config-content-negotiating.xml", 11); - - ContentNegotiatingViewResolver contentNegotiatingViewResolver = appContext.getBean(ContentNegotiatingViewResolver.class); - assertNotNull(contentNegotiatingViewResolver); - DirectFieldAccessor contentNegotiatingViewResolverFieldAccessor = new DirectFieldAccessor(contentNegotiatingViewResolver); - assertTrue((boolean)contentNegotiatingViewResolverFieldAccessor.getPropertyValue("useNotAcceptableStatusCode")); - assertEquals(1, ((List)contentNegotiatingViewResolverFieldAccessor.getPropertyValue("defaultViews")).size()); - assertEquals(7, ((List)contentNegotiatingViewResolverFieldAccessor.getPropertyValue("viewResolvers")).size()); - ContentNegotiationManager contentNegotiationManagerProperty = - (ContentNegotiationManager)contentNegotiatingViewResolverFieldAccessor.getPropertyValue("contentNegotiationManager"); - assertNotNull(contentNegotiationManagerProperty); - ContentNegotiationManager contentNegotiationManager = appContext.getBean(ContentNegotiationManager.class); - assertNotNull(contentNegotiationManager); - assertEquals(contentNegotiationManagerProperty.getClass(), contentNegotiationManager.getClass()); + public void testViewResolutionWithContentNegotiation() throws Exception { + loadBeanDefinitions("mvc-config-view-resolution-content-negotiation.xml", 5); + + ViewResolverComposite compositeResolver = this.appContext.getBean(ViewResolverComposite.class); + assertNotNull(compositeResolver); + assertEquals(1, compositeResolver.getViewResolvers().size()); + assertEquals(Ordered.HIGHEST_PRECEDENCE, compositeResolver.getOrder()); + + List resolvers = compositeResolver.getViewResolvers(); + assertEquals(ContentNegotiatingViewResolver.class, resolvers.get(0).getClass()); + ContentNegotiatingViewResolver cnvr = (ContentNegotiatingViewResolver) resolvers.get(0); + assertEquals(5, cnvr.getViewResolvers().size()); + assertEquals(1, cnvr.getDefaultViews().size()); + assertTrue(cnvr.isUseNotAcceptableStatusCode()); + + String beanName = "contentNegotiationManager"; + DirectFieldAccessor accessor = new DirectFieldAccessor(cnvr); + ContentNegotiationManager manager = (ContentNegotiationManager) accessor.getPropertyValue(beanName); + assertNotNull(manager); + assertSame(manager, this.appContext.getBean(ContentNegotiationManager.class)); } - @Test - public void testContentNegotiatingWithDefaultValues() throws Exception { - loadBeanDefinitions("mvc-config-content-negotiating-with-default-values.xml", 19); - - ContentNegotiatingViewResolver contentNegotiatingViewResolver = appContext.getBean(ContentNegotiatingViewResolver.class); - assertNotNull(contentNegotiatingViewResolver); - DirectFieldAccessor contentNegotiatingViewResolverFieldAccessor = new DirectFieldAccessor(contentNegotiatingViewResolver); - assertEquals(1, ((List)contentNegotiatingViewResolverFieldAccessor.getPropertyValue("defaultViews")).size()); - assertEquals(3, ((List)contentNegotiatingViewResolverFieldAccessor.getPropertyValue("viewResolvers")).size()); - ContentNegotiationManager contentNegotiationManagerProperty = - (ContentNegotiationManager)contentNegotiatingViewResolverFieldAccessor.getPropertyValue("contentNegotiationManager"); - assertNotNull(contentNegotiationManagerProperty); - ContentNegotiationManager contentNegotiationManager = appContext.getBean(ContentNegotiationManager.class); - assertNotNull(contentNegotiationManager); - assertEquals(contentNegotiationManagerProperty.getClass(), contentNegotiationManager.getClass()); - } - - @Test public void testPathMatchingHandlerMappings() throws Exception { loadBeanDefinitions("mvc-config-path-matching-mappings.xml", 20); @@ -673,7 +668,8 @@ public class MvcNamespaceTests { XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext); ClassPathResource resource = new ClassPathResource(fileName, AnnotationDrivenBeanDefinitionParserTests.class); reader.loadBeanDefinitions(resource); - assertEquals(expectedBeanCount, appContext.getBeanDefinitionCount()); + assertEquals("Bean names: " + Arrays.toString(this.appContext.getBeanDefinitionNames()), + expectedBeanCount, appContext.getBeanDefinitionCount()); appContext.refresh(); } diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating-with-default-values.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating-with-default-values.xml deleted file mode 100644 index 3735139a785..00000000000 --- a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating-with-default-values.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating.xml deleted file mode 100644 index 5b6c4613470..00000000000 --- a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - /WEB-INF/pages/ - - - .jsp - - - - - - - xml=application/rss+xml - - - - - - - - - - - - - - - - - - - - - /WEB-INF/pages/ - - - .jsp - - - - - - - - \ No newline at end of file diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiation-manager.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiation-manager.xml index 76fa6539570..34d609b65cb 100644 --- a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiation-manager.xml +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiation-manager.xml @@ -1,10 +1,12 @@ + diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution-content-negotiation.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution-content-negotiation.xml new file mode 100644 index 00000000000..d5a5208d92b --- /dev/null +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution-content-negotiation.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution.xml index f39c3dd89ec..afca9d64072 100644 --- a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution.xml +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution.xml @@ -1,26 +1,34 @@ - + + + + + + + + + - + - + + + + - + + + + - + - - - - \ No newline at end of file