diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java index 86144325f1d..076ce79b252 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * 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. @@ -34,14 +34,7 @@ import org.springframework.test.web.servlet.samples.context.JavaConfigTests.Root import org.springframework.test.web.servlet.samples.context.JavaConfigTests.WebConfig; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; -import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; -import org.springframework.web.servlet.config.annotation.EnableWebMvc; -import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; -import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; -import org.springframework.web.servlet.view.UrlBasedViewResolver; -import org.springframework.web.servlet.view.tiles3.TilesConfigurer; -import org.springframework.web.servlet.view.tiles3.TilesView; +import org.springframework.web.servlet.config.annotation.*; import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*; @@ -54,6 +47,7 @@ import static org.mockito.Mockito.*; * * @author Rossen Stoyanchev * @author Sam Brannen + * @author Sebastien Deleuze */ @RunWith(SpringJUnit4ClassRunner.class) @WebAppConfiguration("src/test/resources/META-INF/web-resources") @@ -130,19 +124,11 @@ public class JavaConfigTests { configurer.enable(); } - @Bean - public UrlBasedViewResolver urlBasedViewResolver() { - UrlBasedViewResolver resolver = new UrlBasedViewResolver(); - resolver.setViewClass(TilesView.class); - return resolver; + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + registry.tiles().definition("/WEB-INF/**/tiles.xml"); } - @Bean - public TilesConfigurer tilesConfigurer() { - TilesConfigurer configurer = new TilesConfigurer(); - configurer.setDefinitions(new String[] {"/WEB-INF/**/tiles.xml"}); - return configurer; - } } } diff --git a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/EncodedUriTests.java b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/EncodedUriTests.java index b1fa6931ff6..cf3e373c8d1 100644 --- a/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/EncodedUriTests.java +++ b/spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/EncodedUriTests.java @@ -40,6 +40,7 @@ import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.context.WebApplicationContext; import org.springframework.web.servlet.config.annotation.EnableWebMvc; +import org.springframework.web.servlet.config.annotation.ViewResolutionRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.util.UriComponentsBuilder; @@ -94,6 +95,11 @@ public class EncodedUriTests { public HandlerMappingConfigurer myHandlerMappingConfigurer() { return new HandlerMappingConfigurer(); } + + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + registry.jsp("", ""); + } } @Controller diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/ViewResolverComposite.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/ViewResolverComposite.java new file mode 100644 index 00000000000..4f2e3241354 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/ViewResolverComposite.java @@ -0,0 +1,100 @@ +/* + * 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; + +import org.springframework.beans.BeansException; +import org.springframework.context.ApplicationContext; +import org.springframework.context.ApplicationContextAware; +import org.springframework.core.Ordered; +import org.springframework.web.context.ServletContextAware; + +import javax.servlet.ServletContext; +import java.util.Collections; +import java.util.List; +import java.util.Locale; + +/** + * A {@link ViewResolverComposite} that delegates to a list of other {@link ViewResolver}s. + * + * @author Sebastien Deleuze + * @since 4.1 + */ +public class ViewResolverComposite implements ApplicationContextAware, ServletContextAware, ViewResolver, Ordered { + + private List viewResolvers; + + private int order = Ordered.LOWEST_PRECEDENCE; + + public void setOrder(int order) { + this.order = order; + } + + @Override + public int getOrder() { + return this.order; + } + + /** + * Set the list of view viewResolvers to delegate to. + */ + public void setViewResolvers(List viewResolvers) { + this.viewResolvers = viewResolvers; + } + + /** + * Return the list of view viewResolvers to delegate to. + */ + public List getViewResolvers() { + return Collections.unmodifiableList(viewResolvers); + } + + @Override + public View resolveViewName(String viewName, Locale locale) throws Exception { + if (viewResolvers != null) { + for (ViewResolver viewResolver : viewResolvers) { + View v = viewResolver.resolveViewName(viewName, locale); + if (v != null) { + return v; + } + } + } + + return null; + } + + @Override + public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { + if (viewResolvers != null) { + for (ViewResolver viewResolver : viewResolvers) { + if(viewResolver instanceof ApplicationContextAware) { + ((ApplicationContextAware)viewResolver).setApplicationContext(applicationContext); + } + } + } + } + + @Override + public void setServletContext(ServletContext servletContext) { + if (viewResolvers != null) { + for (ViewResolver viewResolver : viewResolvers) { + if(viewResolver instanceof ServletContextAware) { + ((ServletContextAware)viewResolver).setServletContext(servletContext); + } + } + } + } +} 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 16c48d081f3..1f7d81d2866 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 @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * 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. @@ -28,14 +28,14 @@ import org.springframework.beans.factory.xml.NamespaceHandlerSupport; */ public class MvcNamespaceHandler extends NamespaceHandlerSupport { - + @Override public void init() { registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser()); registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser()); registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser()); registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser()); registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser()); - registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser()); + registerBeanDefinitionParser("view-resolution", new ViewResolutionBeanDefinitionParser()); } } 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 new file mode 100644 index 00000000000..12234e13f56 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolutionBeanDefinitionParser.java @@ -0,0 +1,252 @@ +/* + * 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 deleted file mode 100644 index 152090acd5c..00000000000 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java +++ /dev/null @@ -1,158 +0,0 @@ -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.parsing.BeanComponentDefinition; -import org.springframework.beans.factory.parsing.CompositeComponentDefinition; -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.xml.DomUtils; -import org.springframework.web.servlet.view.BeanNameViewResolver; -import org.springframework.web.servlet.view.InternalResourceViewResolver; - -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.TilesView; -import org.springframework.web.servlet.view.tiles3.TilesViewResolver; -import org.w3c.dom.Element; - - -public class ViewResolversBeanDefinitionParser implements BeanDefinitionParser { - - private static final String INTERNAL_VIEW_RESOLVER_BEAN_NAME = - "org.springframework.web.servlet.view.InternalResourceViewResolver"; - private static final String TILES3_VIEW_RESOLVER_BEAN_NAME = - "org.springframework.web.servlet.view.tiles3.TilesViewResolver"; - private static final String TILES3_CONFIGURER_BEAN_NAME = - "org.springframework.web.servlet.view.tiles3.TilesConfigurer"; - private static final String BEANNAME_VIEW_RESOLVER_BEAN_NAME = - "org.springframework.web.servlet.view.BeanNameViewResolver"; - private static final String FREEMARKER_CONFIGURER_BEAN_NAME = - "org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer"; - private static final String FREEMARKER_VIEW_RESOLVER_BEAN_NAME = - "org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"; - - private ParserContext parserContext; - private Object source; - - public BeanDefinition parse(Element element, ParserContext parserContext) { - - this.parserContext=parserContext; - - source= parserContext.extractSource(element); - CompositeComponentDefinition compDefinition = new CompositeComponentDefinition(element.getTagName(),source); - parserContext.pushContainingComponent(compDefinition); - - - - List viewResolverElements = //DomUtils.getChildElements(element); - DomUtils.getChildElementsByTagName(element, new String[] { "jsp", "tiles","bean-name","freemarker" }); - for (Element viewResolverElement : viewResolverElements) { - - if ("jsp".equals(viewResolverElement.getLocalName())) { - registerInternalResourceViewResolverBean(parserContext,viewResolverElement); - System.out.println("Registered Internalresource view resolver"); - } - - if("bean-name".equals(viewResolverElement.getLocalName())){ - registerBeanNameViewResolverBean(parserContext,viewResolverElement); - System.out.println("Registered BeanNameViewResolverBean view resolver"); - } - if ("tiles".equals(viewResolverElement.getLocalName())) { - registerTilesViewResolverBean(parserContext,viewResolverElement); - registerTilesConfigurerBean(parserContext,viewResolverElement); - } - if("freemarker".equals(viewResolverElement.getLocalName())){ - registerFreemarkerViewResolverBean(parserContext,viewResolverElement); - registerFreemarkerConfigurerBean(parserContext,viewResolverElement); - } - - } - - // MvcNamespaceUtils.registerDefaultComponents(parserContext, source); - parserContext.popAndRegisterContainingComponent(); - return null; - - - } - - private void registerBean(String beanName,Map propertyMap,Class beanClass ){ - 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)); - } - parserContext.getRegistry().registerBeanDefinition(beanName, beanDef); - parserContext.registerComponent(new BeanComponentDefinition(beanDef, beanName)); - - - } - - private void registerFreemarkerConfigurerBean(ParserContext parserContext, Element viewResolverElement) { - String templateLoaderPath=viewResolverElement.getAttribute("templateLoaderPath"); - Map propertyMap= new HashMap(); - propertyMap.put("templateLoaderPath", templateLoaderPath); - - registerBean(FREEMARKER_CONFIGURER_BEAN_NAME, propertyMap, FreeMarkerConfigurer.class); - - } - - private void registerFreemarkerViewResolverBean(ParserContext parserContext, Element viewResolverElement) { - if (!parserContext.getRegistry().containsBeanDefinition(FREEMARKER_VIEW_RESOLVER_BEAN_NAME)) { - - Map propertyMap= new HashMap(); - propertyMap.put("prefix", viewResolverElement.getAttribute("prefix")); - propertyMap.put("suffix", viewResolverElement.getAttribute("suffix")); - propertyMap.put("order", 4); - registerBean(FREEMARKER_VIEW_RESOLVER_BEAN_NAME, propertyMap, FreeMarkerViewResolver.class); - } - } - - private void registerBeanNameViewResolverBean(ParserContext parserContext, Element viewResolverElement) { - if (!parserContext.getRegistry().containsBeanDefinition(BEANNAME_VIEW_RESOLVER_BEAN_NAME)) { - Map propertyMap= new HashMap(); - propertyMap.put("order", 3); - registerBean(BEANNAME_VIEW_RESOLVER_BEAN_NAME, propertyMap, BeanNameViewResolver.class); - System.out.println("Registered BeanNameViewResolverBean view resolver"); - } - } - - private void registerTilesConfigurerBean(ParserContext parserContext,Element viewResolverElement) { - if (!parserContext.getRegistry().containsBeanDefinition(TILES3_CONFIGURER_BEAN_NAME)) { - Map propertyMap= new HashMap(); - propertyMap.put("definitions", viewResolverElement.getAttribute("definitions")); - registerBean(TILES3_CONFIGURER_BEAN_NAME, propertyMap, TilesConfigurer.class); - } - } - - private void registerTilesViewResolverBean(ParserContext parserContext, Element viewResolverElement) { - - if (!parserContext.getRegistry().containsBeanDefinition(TILES3_VIEW_RESOLVER_BEAN_NAME)) { - Map propertyMap= new HashMap(); - propertyMap.put("viewClass", TilesView.class); - propertyMap.put("order", 1); - registerBean(TILES3_VIEW_RESOLVER_BEAN_NAME, propertyMap, TilesViewResolver.class); - } - } - private void registerInternalResourceViewResolverBean(ParserContext parserContext, Element viewResolverElement) { - if (!parserContext.getRegistry().containsBeanDefinition(INTERNAL_VIEW_RESOLVER_BEAN_NAME)) { - Map propertyMap= new HashMap(); - propertyMap.put("prefix", viewResolverElement.getAttribute("prefix")); - propertyMap.put("suffix", viewResolverElement.getAttribute("suffix")); - propertyMap.put("order", 2); - registerBean(INTERNAL_VIEW_RESOLVER_BEAN_NAME, propertyMap, InternalResourceViewResolver.class); - } - - - } - - - -} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/BeanNameRegistration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/BeanNameRegistration.java new file mode 100644 index 00000000000..9aff9fe1ee3 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/BeanNameRegistration.java @@ -0,0 +1,34 @@ +/* + * 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.annotation; + +import org.springframework.web.servlet.view.BeanNameViewResolver; + +/** + * Encapsulates information required to create a + * {@link org.springframework.web.servlet.view.BeanNameViewResolver} bean. + * + * @author Sebastien Deleuze + * @since 4.1 + */ +public class BeanNameRegistration extends ViewResolutionRegistration { + + public BeanNameRegistration(ViewResolutionRegistry registry) { + super(registry, new BeanNameViewResolver()); + } + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiatingRegistration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiatingRegistration.java new file mode 100644 index 00000000000..1bc875eb2a5 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiatingRegistration.java @@ -0,0 +1,71 @@ +/* + * 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.annotation; + +import org.springframework.web.servlet.View; +import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Encapsulates information required to create a {@link ContentNegotiatingViewResolver} bean. + * + * @author Sebastien Deleuze + * @since 4.1 + */ +public class ContentNegotiatingRegistration extends ViewResolutionRegistration { + + private List defaultViews; + + public ContentNegotiatingRegistration(ViewResolutionRegistry registry) { + super(registry, new ContentNegotiatingViewResolver()); + } + + /** + * Indicate whether a {@link javax.servlet.http.HttpServletResponse#SC_NOT_ACCEPTABLE 406 Not Acceptable} + * status code should be returned if no suitable view can be found. + * + * @see ContentNegotiatingViewResolver#setUseNotAcceptableStatusCode(boolean) + */ + public ContentNegotiatingRegistration useNotAcceptable(boolean useNotAcceptable) { + this.viewResolver.setUseNotAcceptableStatusCode(useNotAcceptable); + return this; + } + + /** + * + * Set the default views to use when a more specific view can not be obtained + * from the {@link org.springframework.web.servlet.ViewResolver} chain. + * + * @see ContentNegotiatingViewResolver#setDefaultViews(java.util.List) + */ + public ContentNegotiatingRegistration defaultViews(View... defaultViews) { + if(this.defaultViews == null) { + this.defaultViews = new ArrayList(); + } + this.defaultViews.addAll(Arrays.asList(defaultViews)); + return this; + } + + @Override + protected ContentNegotiatingViewResolver getViewResolver() { + this.viewResolver.setDefaultViews(this.defaultViews); + return super.getViewResolver(); + } +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java index fef35bcec8d..c8fce889af3 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java @@ -75,6 +75,11 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { this.configurers.addViewControllers(registry); } + @Override + protected void configureViewResolution(ViewResolutionRegistry registry) { + this.configurers.configureViewResolution(registry); + } + @Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { this.configurers.addResourceHandlers(registry); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java index 178569b4c4c..fc585fd72e5 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2012 the original author or authors. + * 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 @@ -84,11 +84,12 @@ import org.springframework.context.annotation.Import; * * @author Dave Syer * @author Rossen Stoyanchev + * @author Sebastien Deleuze * @since 3.1 */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Documented -@Import(DelegatingWebMvcConfiguration.class) +@Import({DelegatingWebMvcConfiguration.class, ViewConfigurationsImportSelector.class}) public @interface EnableWebMvc { } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerConfigurerConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerConfigurerConfigurationSupport.java new file mode 100644 index 00000000000..bb5bce33146 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerConfigurerConfigurationSupport.java @@ -0,0 +1,59 @@ +/* + * 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.annotation; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; + +import java.util.List; + +/** + * This class creates a FreeMarkerConfigurer bean. + * It is typically imported by adding {@link EnableWebMvc @EnableWebMvc} to an + * application {@link Configuration @Configuration} class when FreeMarker is + * in the classpath. + * + * @author Sebastien Deleuze + * @since 4.1 + * @see org.springframework.web.servlet.config.annotation.ViewConfigurationsImportSelector + */ +@Configuration +public class FreeMarkerConfigurerConfigurationSupport { + + private List webMvcConfigurationSupports; + + @Autowired(required = false) + public void setWebMvcConfigurationSupports(List webMvcConfigurationSupports) { + this.webMvcConfigurationSupports = webMvcConfigurationSupports; + } + + @Bean + public FreeMarkerConfigurer freeMarkerConfigurer() { + FreeMarkerConfigurer configurer = null; + if(webMvcConfigurationSupports != null) { + for(WebMvcConfigurationSupport configurationSupport : webMvcConfigurationSupports) { + configurer = configurationSupport.getViewResolutionRegistry().getFreeMarkerConfigurer(); + if(configurer != null) { + break; + } + } + } + return configurer; + } +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerRegistration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerRegistration.java new file mode 100644 index 00000000000..65cdfda8809 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerRegistration.java @@ -0,0 +1,94 @@ +/* + * 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.annotation; + +import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; +import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver; + +import java.util.Arrays; +import java.util.List; + +/** + * Encapsulates information required to create a + * {@link org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver} and a + * {@link org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer} beans. + * Default configuration is "" prefix, ".ftl" suffix and "/WEB-INF/" templateLoaderPath. + * + * @author Sebastien Deleuze + * @since 4.1 + */ +public class FreeMarkerRegistration extends ViewResolutionRegistration { + + private final FreeMarkerConfigurer configurer; + private List templateLoaderPaths; + + public FreeMarkerRegistration(ViewResolutionRegistry registry) { + super(registry, new FreeMarkerViewResolver()); + this.configurer = new FreeMarkerConfigurer(); + this.prefix(""); + this.suffix(".ftl"); + this.templateLoaderPath("/WEB-INF/"); + } + + /** + * Set the prefix that gets prepended to view names when building a URL. + * + * @see org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver#setPrefix(String) + */ + public FreeMarkerRegistration prefix(String prefix) { + this.viewResolver.setPrefix(prefix); + return this; + } + + /** + * Set the suffix that gets appended to view names when building a URL. + * + * @see org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver#setSuffix(String) + */ + public FreeMarkerRegistration suffix(String suffix) { + this.viewResolver.setSuffix(suffix); + return this; + } + + /** + * Enable or disable caching. + * + * @see org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver#setCache(boolean) + */ + public FreeMarkerRegistration cache(boolean cache) { + this.viewResolver.setCache(cache); + return this; + } + + /** + * Set a List of {@code TemplateLoader}s that will be used to search + * for templates. + * + * @see org.springframework.ui.freemarker.FreeMarkerConfigurationFactory#setTemplateLoaderPaths(String...) + */ + public FreeMarkerRegistration templateLoaderPath(String... templateLoaderPath) { + this.templateLoaderPaths= Arrays.asList(templateLoaderPath); + return this; + } + + protected FreeMarkerConfigurer getConfigurer() { + if(this.templateLoaderPaths != null && !this.templateLoaderPaths.isEmpty()) { + this.configurer.setTemplateLoaderPaths(this.templateLoaderPaths.toArray(new String[0])); + } + return this.configurer; + } +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/JspRegistration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/JspRegistration.java new file mode 100644 index 00000000000..bfa401320f1 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/JspRegistration.java @@ -0,0 +1,40 @@ +/* + * 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.annotation; + +import org.springframework.web.servlet.view.InternalResourceViewResolver; + +/** + * Encapsulates information required to create an {@link InternalResourceViewResolver} bean. + * Default configuration is "/WEB-INF/" prefix and ".jsp" suffix. + * + * @author Sebastien Deleuze + * @since 4.1 + */ +public class JspRegistration extends ViewResolutionRegistration { + + public JspRegistration(ViewResolutionRegistry registry) { + this(registry, "/WEB-INF/", ".jsp"); + } + + public JspRegistration(ViewResolutionRegistry registry, String prefix, String suffix) { + super(registry, new InternalResourceViewResolver()); + this.viewResolver.setPrefix(prefix); + this.viewResolver.setSuffix(suffix); + } + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesConfigurerConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesConfigurerConfigurationSupport.java new file mode 100644 index 00000000000..c41627fd5bd --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesConfigurerConfigurationSupport.java @@ -0,0 +1,59 @@ +/* + * 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.annotation; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.view.tiles3.TilesConfigurer; + +import java.util.List; + +/** + * This class creates a TilesConfigurer bean. + * It is typically imported by adding {@link EnableWebMvc @EnableWebMvc} to an + * application {@link Configuration @Configuration} class when Tiles 3 is + * in the classpath. + * + * @author Sebastien Deleuze + * @since 4.1 + * @see org.springframework.web.servlet.config.annotation.ViewConfigurationsImportSelector + */ +@Configuration +public class TilesConfigurerConfigurationSupport { + + private List webMvcConfigurationSupports; + + @Autowired(required = false) + public void setWebMvcConfigurationSupports(List webMvcConfigurationSupports) { + this.webMvcConfigurationSupports = webMvcConfigurationSupports; + } + + @Bean + public TilesConfigurer tilesConfigurer() { + TilesConfigurer configurer = null; + if(webMvcConfigurationSupports != null) { + for(WebMvcConfigurationSupport configurationSupport : webMvcConfigurationSupports) { + configurer = configurationSupport.getViewResolutionRegistry().getTilesConfigurer(); + if(configurer != null) { + break; + } + } + } + return configurer; + } +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesRegistration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesRegistration.java new file mode 100644 index 00000000000..718ee4e260d --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesRegistration.java @@ -0,0 +1,99 @@ +/* + * 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.annotation; + +import org.springframework.web.servlet.view.tiles3.TilesConfigurer; +import org.springframework.web.servlet.view.tiles3.TilesViewResolver; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Encapsulates information required to create a + * {@link org.springframework.web.servlet.view.tiles3.TilesViewResolver} and a + * {@link org.springframework.web.servlet.view.tiles3.TilesConfigurer} beans. + * + * Default definition is "/WEB-INF/tiles.xml" and no Tiles definition check refresh. + * + * @author Sebastien Deleuze + * @since 4.1 + */ +public class TilesRegistration extends ViewResolutionRegistration { + + private List definitions; + private Boolean checkRefresh; + + public TilesRegistration(ViewResolutionRegistry registry) { + super(registry, new TilesViewResolver()); + } + + /** + * Set the prefix that gets prepended to view names when building a URL. + * + * @see TilesViewResolver#setPrefix(String) + */ + public TilesRegistration prefix(String prefix) { + this.viewResolver.setPrefix(prefix); + return this; + } + + /** + * Set the suffix that gets appended to view names when building a URL. + * + * @see TilesViewResolver#setSuffix(String) + */ + public TilesRegistration suffix(String suffix) { + this.viewResolver.setSuffix(suffix); + return this; + } + + /** + * Set the Tiles definitions, i.e. a single value or a list of files containing the definitions. + * + * @see TilesConfigurer#setDefinitions(String...) + */ + public TilesRegistration definition(String... definitions) { + if(this.definitions == null) { + this.definitions = new ArrayList(); + } + this.definitions.addAll(Arrays.asList(definitions)); + return this; + } + + /** + * Set whether to check Tiles definition files for a refresh at runtime. + * + * @see TilesConfigurer#setCheckRefresh(boolean) + */ + public TilesRegistration checkRefresh(boolean checkRefresh) { + this.checkRefresh = checkRefresh; + return this; + } + + protected TilesConfigurer getTilesConfigurer() { + TilesConfigurer tilesConfigurer = new TilesConfigurer(); + if(this.definitions != null && !this.definitions.isEmpty()) { + tilesConfigurer.setDefinitions(this.definitions.toArray(new String[0])); + } + if(this.checkRefresh != null) { + tilesConfigurer.setCheckRefresh(this.checkRefresh); + } + return tilesConfigurer; + } + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityConfigurerConfigurationSupport.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityConfigurerConfigurationSupport.java new file mode 100644 index 00000000000..dee57694a44 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityConfigurerConfigurationSupport.java @@ -0,0 +1,59 @@ +/* + * 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.annotation; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.view.velocity.VelocityConfigurer; + +import java.util.List; + +/** + * This class creates the VelocityConfigurer bean. + * It is typically imported by adding {@link EnableWebMvc @EnableWebMvc} to an + * application {@link Configuration @Configuration} class when Velocity in the classpath. + * + * @author Sebastien Deleuze + * @since 4.1 + * @see org.springframework.web.servlet.config.annotation.ViewConfigurationsImportSelector + */ +@Configuration +public class VelocityConfigurerConfigurationSupport { + + private List webMvcConfigurationSupports; + + @Autowired(required = false) + public void setWebMvcConfigurationSupports(List webMvcConfigurationSupports) { + this.webMvcConfigurationSupports = webMvcConfigurationSupports; + } + + @Bean + public VelocityConfigurer velocityConfigurer() { + VelocityConfigurer configurer = null; + if(webMvcConfigurationSupports != null) { + for(WebMvcConfigurationSupport configurationSupport : webMvcConfigurationSupports) { + configurer = configurationSupport.getViewResolutionRegistry().getVelocityConfigurer(); + if(configurer != null) { + break; + } + } + } + return configurer; + } + +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityRegistration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityRegistration.java new file mode 100644 index 00000000000..bbf4e758435 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityRegistration.java @@ -0,0 +1,86 @@ +/* + * 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.annotation; + +import org.springframework.web.servlet.view.velocity.VelocityConfigurer; +import org.springframework.web.servlet.view.velocity.VelocityViewResolver; + +/** + * Encapsulates information required to create a + * {@link org.springframework.web.servlet.view.velocity.VelocityViewResolver} and a + * {@link org.springframework.web.servlet.view.velocity.VelocityConfigurer beans}. + * Default configuration is "" prefix, ".vm" suffix and "/WEB-INF/" resourceLoaderPath. + * + * @author Sebastien Deleuze + * @since 4.1 + */ +public class VelocityRegistration extends ViewResolutionRegistration { + + private final VelocityConfigurer configurer; + + public VelocityRegistration(ViewResolutionRegistry registry) { + super(registry, new VelocityViewResolver()); + this.configurer = new VelocityConfigurer(); + this.prefix(""); + this.suffix(".vm"); + this.resourceLoaderPath("/WEB-INF/"); + } + + /** + * Set the Velocity resource loader path via a Spring resource location. + * + * @see org.springframework.web.servlet.view.velocity.VelocityConfigurer#setResourceLoaderPath(String) + */ + public VelocityRegistration resourceLoaderPath(String resourceLoaderPath) { + this.configurer.setResourceLoaderPath(resourceLoaderPath); + return this; + } + + /** + * Set the prefix that gets prepended to view names when building a URL. + * + * @see org.springframework.web.servlet.view.velocity.VelocityViewResolver#setPrefix(String) + */ + public VelocityRegistration prefix(String prefix) { + this.viewResolver.setPrefix(prefix); + return this; + } + + /** + * Set the suffix that gets appended to view names when building a URL. + * + * @see org.springframework.web.servlet.view.velocity.VelocityViewResolver#setSuffix(String) + */ + public VelocityRegistration suffix(String suffix) { + this.viewResolver.setSuffix(suffix); + return this; + } + + /** + * Enable or disable caching. + * + * @see org.springframework.web.servlet.view.velocity.VelocityViewResolver#setCache(boolean) + */ + public VelocityRegistration cache(boolean cache) { + this.viewResolver.setCache(cache); + return this; + } + + protected VelocityConfigurer getConfigurer() { + return this.configurer; + } +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewConfigurationsImportSelector.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewConfigurationsImportSelector.java new file mode 100644 index 00000000000..7d801a9e3c7 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewConfigurationsImportSelector.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.annotation; + +import org.springframework.context.annotation.ImportSelector; +import org.springframework.core.type.AnnotationMetadata; +import org.springframework.util.ClassUtils; + +import java.util.ArrayList; +import java.util.List; + +/** + * This class imports @{@link org.springframework.context.annotation.Configuration} + * classes for view configurers based on a classpath criteria. + * + * @author Sebastien Deleuze + * @since 4.1 + */ +public class ViewConfigurationsImportSelector implements ImportSelector { + + private static final boolean tilesPresent = + ClassUtils.isPresent("org.apache.tiles.startup.TilesInitializer", ViewConfigurationsImportSelector.class.getClassLoader()); + + private static final boolean velocityPresent = + ClassUtils.isPresent("org.apache.velocity.app.VelocityEngine", ViewConfigurationsImportSelector.class.getClassLoader()); + + private static final boolean freeMarkerPresent = + ClassUtils.isPresent("freemarker.template.Configuration", ViewConfigurationsImportSelector.class.getClassLoader()); + + @Override + public String[] selectImports(AnnotationMetadata importingClassMetadata) { + List configurationClasses = new ArrayList(); + if(tilesPresent) { + configurationClasses.add(TilesConfigurerConfigurationSupport.class.getName()); + } + if(velocityPresent) { + configurationClasses.add(VelocityConfigurerConfigurationSupport.class.getName()); + } + if(freeMarkerPresent) { + configurationClasses.add(FreeMarkerConfigurerConfigurationSupport.class.getName()); + } + return configurationClasses.toArray(new String[0]); + } +} diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistration.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistration.java new file mode 100644 index 00000000000..c15b7392479 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistration.java @@ -0,0 +1,48 @@ +/* + * 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.annotation; + +import org.springframework.web.servlet.ViewResolver; + +/** + * Encapsulates information required to create a view resolver. + * + * @author Sebastien Deleuze + * @since 4.1 + */ +public class ViewResolutionRegistration { + + protected final ViewResolutionRegistry registry; + + protected final T viewResolver; + + public ViewResolutionRegistration(ViewResolutionRegistry registry, T viewResolver) { + this.registry = registry; + this.viewResolver = viewResolver; + } + + public ViewResolutionRegistry and() { + return this.registry; + } + + protected T getViewResolver() { + return this.viewResolver; + } + +} + + diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistry.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistry.java new file mode 100644 index 00000000000..489bbfea423 --- /dev/null +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistry.java @@ -0,0 +1,164 @@ +/* + * 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.annotation; + +import org.springframework.web.servlet.View; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer; +import org.springframework.web.servlet.view.tiles3.TilesConfigurer; +import org.springframework.web.servlet.view.velocity.VelocityConfigurer; + +import java.util.ArrayList; +import java.util.List; + +/** + * Helps with configuring a list of view resolvers. + * + * @author Sebastien Deleuze + * @since 4.1 + */ +public class ViewResolutionRegistry { + + private final List> registrations = new ArrayList>(); + + /** + * Register a custom {@link ViewResolver} bean. + */ + public ViewResolutionRegistration addViewResolver(ViewResolver viewResolver) { + ViewResolutionRegistration registration = new ViewResolutionRegistration(this, viewResolver); + registrations.add(registration); + return registration; + } + + /** + * Register an {@link org.springframework.web.servlet.view.InternalResourceViewResolver} + * bean with default "/WEB-INF/" prefix and ".jsp" suffix. + */ + public JspRegistration jsp() { + JspRegistration registration = new JspRegistration(this); + addAndCheckViewResolution(registration); + return registration; + } + + /** + * Register an {@link org.springframework.web.servlet.view.InternalResourceViewResolver} + * bean with specified prefix and suffix. + */ + public JspRegistration jsp(String prefix, String suffix) { + JspRegistration registration = new JspRegistration(this, prefix, suffix); + addAndCheckViewResolution(registration); + return registration; + } + + /** + * Register a {@link org.springframework.web.servlet.view.BeanNameViewResolver} bean. + */ + public BeanNameRegistration beanName() { + BeanNameRegistration registration = new BeanNameRegistration(this); + addAndCheckViewResolution(registration); + return registration; + } + + /** + * Register a {@link org.springframework.web.servlet.view.tiles3.TilesViewResolver} and + * a {@link org.springframework.web.servlet.view.tiles3.TilesConfigurer} with + * default "/WEB-INF/tiles.xml" definition and no Tiles definition check refresh. + */ + public TilesRegistration tiles() { + TilesRegistration registration = new TilesRegistration(this); + addAndCheckViewResolution(registration); + return registration; + } + + /** + * Register a {@link org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver} + * and a {@link org.springframework.web.servlet.view.velocity.VelocityConfigurer} beans with + * default "" prefix, ".vm" suffix and "/WEB-INF/" resourceLoaderPath. + */ + public VelocityRegistration velocity() { + VelocityRegistration registration = new VelocityRegistration(this); + addAndCheckViewResolution(registration); + return registration; + } + + /** + * Register a {@link org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver} + * and a {@link org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer} beans with + * "" prefix, ".ftl" suffix and "/WEB-INF/" templateLoaderPath. + */ + public FreeMarkerRegistration freemarker() { + FreeMarkerRegistration registration = new FreeMarkerRegistration(this); + addAndCheckViewResolution(registration); + return registration; + } + + /** + * Register a {@link org.springframework.web.servlet.view.ContentNegotiatingViewResolver} bean. + */ + public ContentNegotiatingRegistration contentNegotiating(View... defaultViews) { + ContentNegotiatingRegistration registration = new ContentNegotiatingRegistration(this); + registration.defaultViews(defaultViews); + addAndCheckViewResolution(registration); + return registration; + } + + protected List getViewResolvers() { + List viewResolvers = new ArrayList(); + + for(ViewResolutionRegistration registration : this.registrations) { + viewResolvers.add(registration.getViewResolver()); + } + return viewResolvers; + } + + protected TilesConfigurer getTilesConfigurer() { + for(ViewResolutionRegistration registration : this.registrations) { + if(registration instanceof TilesRegistration) { + return ((TilesRegistration) registration).getTilesConfigurer(); + } + } + return null; + } + + protected FreeMarkerConfigurer getFreeMarkerConfigurer() { + for(ViewResolutionRegistration registration : this.registrations) { + if(registration instanceof FreeMarkerRegistration) { + return ((FreeMarkerRegistration) registration).getConfigurer(); + } + } + return null; + } + + protected VelocityConfigurer getVelocityConfigurer() { + for(ViewResolutionRegistration registration : this.registrations) { + if(registration instanceof VelocityRegistration) { + return ((VelocityRegistration) registration).getConfigurer(); + } + } + return null; + } + + private void addAndCheckViewResolution(ViewResolutionRegistration registration) { + for(ViewResolutionRegistration existingRegistration : this.registrations) { + if(existingRegistration.getClass().equals(registration.getClass())) { + throw new IllegalStateException("An instance of " + registration.getClass().getSimpleName() + + " is already registered, and multiple view resolvers and configurers beans are not supported by this registry"); + } + } + registrations.add(registration); + } +} 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 cd706bcb2f6..24e7e858484 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 @@ -64,9 +64,7 @@ import org.springframework.web.context.ServletContextAware; import org.springframework.web.method.support.CompositeUriComponentsContributor; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.HandlerMethodReturnValueHandler; -import org.springframework.web.servlet.HandlerAdapter; -import org.springframework.web.servlet.HandlerExceptionResolver; -import org.springframework.web.servlet.HandlerMapping; +import org.springframework.web.servlet.*; import org.springframework.web.servlet.handler.AbstractHandlerMapping; import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping; import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor; @@ -83,6 +81,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice; import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver; import org.springframework.web.servlet.resource.ResourceUrlProvider; import org.springframework.web.servlet.resource.ResourceUrlProviderExposingInterceptor; +import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; import org.springframework.web.util.UrlPathHelper; /** @@ -150,12 +149,25 @@ import org.springframework.web.util.UrlPathHelper; * libraries available on the classpath. * * + *

When extending directly from this class instead of using + * {@link EnableWebMvc @EnableWebMvc}, an extra step is needed if you want to use Tiles, FreeMarker + * or Velocity view resolution configuration. Since view configurer beans are registered in their own + * {@link org.springframework.web.servlet.config.annotation.TilesConfigurerConfigurationSupport}, + * {@link org.springframework.web.servlet.config.annotation.FreeMarkerConfigurerConfigurationSupport} + * and {@link org.springframework.web.servlet.config.annotation.VelocityConfigurerConfigurationSupport} + * classes, you should also extend those configuration classes (only the ones + * related to the view technology you are using), or register your own + * {@link org.springframework.web.servlet.view.tiles3.TilesConfigurer}, + * {@link org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer} or + * {@link org.springframework.web.servlet.view.velocity.VelocityConfigurer} beans. + * * @see EnableWebMvc * @see WebMvcConfigurer * @see WebMvcConfigurerAdapter * * @author Rossen Stoyanchev * @author Brian Clozel + * @author Sebastien Deleuze * @since 3.1 */ public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware { @@ -186,6 +198,7 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv private PathMatchConfigurer pathMatchConfigurer; + private ViewResolutionRegistry viewResolutionRegistry; /** * Set the {@link javax.servlet.ServletContext}, e.g. for resource handling, @@ -342,6 +355,13 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv protected void addViewControllers(ViewControllerRegistry registry) { } + /** + * Override this method to configure view resolution. + * @see ViewResolutionRegistry + */ + protected void configureViewResolution(ViewResolutionRegistry registry) { + } + /** * Return a {@link BeanNameUrlHandlerMapping} ordered at 2 to map URL * paths to controller bean names. @@ -771,6 +791,46 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv exceptionResolvers.add(new DefaultHandlerExceptionResolver()); } + /** + * Register a {@link ViewResolverComposite} that contains an ordered list of + * view resolvers obtained either through + * {@link #configureViewResolution(ViewResolutionRegistry)}. + */ + @Bean + public ViewResolverComposite viewResolverComposite() { + ViewResolutionRegistry registry = getViewResolutionRegistry(); + ViewResolverComposite compositeViewResolver = new ViewResolverComposite(); + List viewResolvers = registry.getViewResolvers(); + ContentNegotiatingViewResolver contentNegotiatingViewResolver = null; + List filteredViewResolvers = new ArrayList(); + for(ViewResolver viewResolver : viewResolvers) { + if(viewResolver instanceof ContentNegotiatingViewResolver) { + contentNegotiatingViewResolver = (ContentNegotiatingViewResolver)viewResolver; + contentNegotiatingViewResolver.setContentNegotiationManager(this.mvcContentNegotiationManager()); + } else { + filteredViewResolvers.add(viewResolver); + } + } + if(contentNegotiatingViewResolver != null) { + contentNegotiatingViewResolver.setViewResolvers(filteredViewResolvers); + viewResolvers = new ArrayList(); + viewResolvers.add(contentNegotiatingViewResolver); + } + compositeViewResolver.setViewResolvers(viewResolvers); + compositeViewResolver.setApplicationContext(this.applicationContext); + compositeViewResolver.setServletContext(this.servletContext); + + return compositeViewResolver; + } + + protected ViewResolutionRegistry getViewResolutionRegistry() { + if(this.viewResolutionRegistry == null) { + this.viewResolutionRegistry = new ViewResolutionRegistry(); + configureViewResolution(this.viewResolutionRegistry); + } + return this.viewResolutionRegistry; + } + private final static class EmptyHandlerMapping extends AbstractHandlerMapping { @Override diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java index 6af00bf29b9..80ec304b380 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java @@ -138,6 +138,11 @@ public interface WebMvcConfigurer { */ void addViewControllers(ViewControllerRegistry registry); + /** + * Configure view resolution to translate view names to view implementations. + */ + void configureViewResolution(ViewResolutionRegistry registry); + /** * Add handlers to serve static resources such as images, js, and, css * files from specific locations under web application root, the classpath, diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java index 69d43fb0156..2c8bb9d0320 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java @@ -133,6 +133,14 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { public void addViewControllers(ViewControllerRegistry registry) { } + /** + * {@inheritDoc} + *

This implementation is empty. + */ + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + } + /** * {@inheritDoc} *

This implementation is empty. diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java index 2cea34d6b12..d01bc4fc466 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java @@ -113,6 +113,13 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer { } } + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + for (WebMvcConfigurer delegate : this.delegates) { + delegate.configureViewResolution(registry); + } + } + @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { for (WebMvcConfigurer delegate : this.delegates) { diff --git a/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.0.xsd b/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.0.xsd index 81ddc92171b..5846e0f3914 100644 --- a/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.0.xsd +++ b/spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.0.xsd @@ -515,33 +515,5 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - 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 a12832ed220..be2cc1cacf7 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,5 +598,221 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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 f64c8a8c34b..7b11724d078 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 @@ -51,7 +51,7 @@ import org.springframework.validation.Errors; import org.springframework.validation.Validator; import org.springframework.validation.annotation.Validated; import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; -import org.springframework.web.accept.ContentNegotiationManager; +import org.springframework.web.accept.*; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.context.request.NativeWebRequest; @@ -84,13 +84,13 @@ import org.springframework.web.servlet.resource.ResourceResolver; import org.springframework.web.servlet.resource.ResourceTransformer; import org.springframework.web.servlet.theme.ThemeChangeInterceptor; import org.springframework.web.util.UrlPathHelper; -import org.springframework.web.servlet.view.BeanNameViewResolver; -import org.springframework.web.servlet.view.InternalResourceView; -import org.springframework.web.servlet.view.InternalResourceViewResolver; +import org.springframework.web.servlet.view.*; 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 static org.junit.Assert.*; @@ -99,6 +99,7 @@ import static org.junit.Assert.*; * @author Arjen Poutsma * @author Jeremy Grelle * @author Brian Clozel + * @author Sebastien Deleuze */ public class MvcNamespaceTests { @@ -556,32 +557,95 @@ public class MvcNamespaceTests { } @Test - public void testViewResolvers() throws Exception{ - loadBeanDefinitions("mvc-config-view-resolvers.xml", 6); - InternalResourceViewResolver internalResourceViewResolver=appContext.getBean(InternalResourceViewResolver.class); + public void testViewResolvers() throws Exception { + loadBeanDefinitions("mvc-config-view-resolution.xml", 8); + + InternalResourceViewResolver internalResourceViewResolver = appContext.getBean(InternalResourceViewResolver.class); assertNotNull(internalResourceViewResolver); - InternalResourceView jstlView=(InternalResourceView) internalResourceViewResolver.resolveViewName("xyz", Locale.ENGLISH); - assertEquals(jstlView.getUrl(), "/WEB-INF/xyz.jsp"); + assertEquals(0, internalResourceViewResolver.getOrder()); + DirectFieldAccessor internalResourceViewResolverFieldAccessor = new DirectFieldAccessor(internalResourceViewResolver); + assertEquals("/WEB-INF/", internalResourceViewResolverFieldAccessor.getPropertyValue("prefix")); + assertEquals(".jsp", internalResourceViewResolverFieldAccessor.getPropertyValue("suffix")); - BeanNameViewResolver beanNameUrlHandlerMapping=appContext.getBean(BeanNameViewResolver.class); - assertNotNull(beanNameUrlHandlerMapping); + BeanNameViewResolver beanNameViewResolver = appContext.getBean(BeanNameViewResolver.class); + assertNotNull(beanNameViewResolver); + assertEquals(1, beanNameViewResolver.getOrder()); - TilesConfigurer tilesConfigurer=appContext.getBean(TilesConfigurer.class); + 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); + TilesViewResolver tilesViewResolver = appContext.getBean(TilesViewResolver.class); assertNotNull(tilesViewResolver); + assertEquals(2, tilesViewResolver.getOrder()); - FreeMarkerConfigurer freeMarkerConfigurer=appContext.getBean(FreeMarkerConfigurer.class); + 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); + 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")); + + 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")); } - + @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()); + } + + @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); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistryTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistryTests.java new file mode 100644 index 00000000000..666f941d473 --- /dev/null +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistryTests.java @@ -0,0 +1,205 @@ +/* + * 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.annotation; + +import org.junit.Before; +import org.junit.Test; +import org.springframework.beans.DirectFieldAccessor; +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.freemarker.FreeMarkerConfigurer; +import org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver; +import org.springframework.web.servlet.view.json.MappingJackson2JsonView; +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 static org.junit.Assert.*; +import static org.junit.Assert.assertEquals; + +/** + * Test fixture with a {@link ViewResolutionRegistry}. + * + * @author Sebastien Deleuze + */ +public class ViewResolutionRegistryTests { + + private ViewResolutionRegistry registry; + + @Before + public void setUp() { + registry = new ViewResolutionRegistry(); + } + + @Test + public void noViewResolution() { + assertNotNull(registry.getViewResolvers()); + assertEquals(0, registry.getViewResolvers().size()); + } + + @Test + public void customViewResolution() { + InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); + viewResolver.setPrefix("/"); + viewResolver.setSuffix(".jsp"); + registry.addViewResolver(viewResolver); + assertEquals(InternalResourceViewResolver.class, registry.getViewResolvers().get(0).getClass()); + InternalResourceViewResolver resolver = (InternalResourceViewResolver)registry.getViewResolvers().get(0); + DirectFieldAccessor resolverDirectFieldAccessor = new DirectFieldAccessor(resolver); + assertEquals("/", resolverDirectFieldAccessor.getPropertyValue("prefix")); + assertEquals(".jsp", resolverDirectFieldAccessor.getPropertyValue("suffix")); + } + + @Test + public void beanNameViewResolution() { + registry.beanName(); + assertNotNull(registry.getViewResolvers()); + assertEquals(1, registry.getViewResolvers().size()); + assertEquals(BeanNameViewResolver.class, registry.getViewResolvers().get(0).getClass()); + } + + @Test + public void jspViewResolution() { + registry.jsp("/", ".jsp"); + assertNotNull(registry.getViewResolvers()); + assertEquals(1, registry.getViewResolvers().size()); + assertEquals(InternalResourceViewResolver.class, registry.getViewResolvers().get(0).getClass()); + InternalResourceViewResolver resolver = (InternalResourceViewResolver)registry.getViewResolvers().get(0); + DirectFieldAccessor resolverDirectFieldAccessor = new DirectFieldAccessor(resolver); + assertEquals("/", resolverDirectFieldAccessor.getPropertyValue("prefix")); + assertEquals(".jsp", resolverDirectFieldAccessor.getPropertyValue("suffix")); + } + + @Test + public void defaultJspViewResolution() { + registry.jsp(); + assertNotNull(registry.getViewResolvers()); + assertEquals(1, registry.getViewResolvers().size()); + assertEquals(InternalResourceViewResolver.class, registry.getViewResolvers().get(0).getClass()); + InternalResourceViewResolver resolver = (InternalResourceViewResolver)registry.getViewResolvers().get(0); + DirectFieldAccessor resolverDirectFieldAccessor = new DirectFieldAccessor(resolver); + assertEquals("/WEB-INF/", resolverDirectFieldAccessor.getPropertyValue("prefix")); + assertEquals(".jsp", resolverDirectFieldAccessor.getPropertyValue("suffix")); + } + + @Test + public void tilesViewResolution() { + registry.tiles().checkRefresh(true).definition("def1").definition("def2"); + assertNotNull(registry.getViewResolvers()); + assertEquals(1, registry.getViewResolvers().size()); + assertEquals(TilesViewResolver.class, registry.getViewResolvers().get(0).getClass()); + + assertNotNull(registry.getTilesConfigurer()); + TilesConfigurer configurer = registry.getTilesConfigurer(); + DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(configurer); + assertTrue((boolean) configurerDirectFieldAccessor.getPropertyValue("checkRefresh")); + assertNotNull(configurerDirectFieldAccessor.getPropertyValue("definitions")); + String[] definitions = (String[])configurerDirectFieldAccessor.getPropertyValue("definitions"); + assertEquals(2, definitions.length); + assertEquals("def1", definitions[0]); + assertEquals("def2", definitions[1]); + } + + @Test + public void velocityViewResolution() { + registry.velocity().prefix("/").suffix(".vm").cache(true).resourceLoaderPath("testResourceLoaderPath"); + assertNotNull(registry.getViewResolvers()); + assertEquals(1, registry.getViewResolvers().size()); + assertEquals(VelocityViewResolver.class, registry.getViewResolvers().get(0).getClass()); + VelocityViewResolver resolver = (VelocityViewResolver)registry.getViewResolvers().get(0); + DirectFieldAccessor resolverDirectFieldAccessor = new DirectFieldAccessor(resolver); + assertEquals("/", resolverDirectFieldAccessor.getPropertyValue("prefix")); + assertEquals(".vm", resolverDirectFieldAccessor.getPropertyValue("suffix")); + assertEquals(1024, resolverDirectFieldAccessor.getPropertyValue("cacheLimit")); + + assertNotNull(registry.getVelocityConfigurer()); + VelocityConfigurer configurer = registry.getVelocityConfigurer(); + DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(configurer); + assertEquals("testResourceLoaderPath", configurerDirectFieldAccessor.getPropertyValue("resourceLoaderPath")); + } + + @Test + public void defaultVelocityViewResolution() { + registry.velocity(); + assertNotNull(registry.getViewResolvers()); + assertEquals(1, registry.getViewResolvers().size()); + assertEquals(VelocityViewResolver.class, registry.getViewResolvers().get(0).getClass()); + VelocityViewResolver resolver = (VelocityViewResolver)registry.getViewResolvers().get(0); + DirectFieldAccessor resolverDirectFieldAccessor = new DirectFieldAccessor(resolver); + assertEquals("", resolverDirectFieldAccessor.getPropertyValue("prefix")); + assertEquals(".vm", resolverDirectFieldAccessor.getPropertyValue("suffix")); + + assertNotNull(registry.getVelocityConfigurer()); + VelocityConfigurer configurer = registry.getVelocityConfigurer(); + DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(configurer); + assertEquals("/WEB-INF/", configurerDirectFieldAccessor.getPropertyValue("resourceLoaderPath")); + } + + @Test + public void freeMarkerViewResolution() { + registry.freemarker().prefix("/").suffix(".fmt").cache(false).templateLoaderPath("path1", "path2"); + assertNotNull(registry.getViewResolvers()); + assertEquals(1, registry.getViewResolvers().size()); + assertEquals(FreeMarkerViewResolver.class, registry.getViewResolvers().get(0).getClass()); + FreeMarkerViewResolver resolver = (FreeMarkerViewResolver)registry.getViewResolvers().get(0); + DirectFieldAccessor resolverDirectFieldAccessor = new DirectFieldAccessor(resolver); + assertEquals("/", resolverDirectFieldAccessor.getPropertyValue("prefix")); + assertEquals(".fmt", resolverDirectFieldAccessor.getPropertyValue("suffix")); + assertEquals(0, resolverDirectFieldAccessor.getPropertyValue("cacheLimit")); + + assertNotNull(registry.getFreeMarkerConfigurer()); + FreeMarkerConfigurer configurer = registry.getFreeMarkerConfigurer(); + DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(configurer); + assertNotNull(configurerDirectFieldAccessor.getPropertyValue("templateLoaderPaths")); + String[] templateLoaderPaths = (String[])configurerDirectFieldAccessor.getPropertyValue("templateLoaderPaths"); + assertEquals(2, templateLoaderPaths.length); + assertEquals("path1", templateLoaderPaths[0]); + assertEquals("path2", templateLoaderPaths[1]); + } + + @Test + public void defaultFreeMarkerViewResolution() { + registry.freemarker(); + assertNotNull(registry.getViewResolvers()); + assertEquals(1, registry.getViewResolvers().size()); + assertEquals(FreeMarkerViewResolver.class, registry.getViewResolvers().get(0).getClass()); + FreeMarkerViewResolver resolver = (FreeMarkerViewResolver)registry.getViewResolvers().get(0); + DirectFieldAccessor resolverDirectFieldAccessor = new DirectFieldAccessor(resolver); + assertEquals("", resolverDirectFieldAccessor.getPropertyValue("prefix")); + assertEquals(".ftl", resolverDirectFieldAccessor.getPropertyValue("suffix")); + DirectFieldAccessor configurerDirectFieldAccessor = new DirectFieldAccessor(registry.getFreeMarkerConfigurer()); + assertArrayEquals(new String[]{"/WEB-INF/"}, (String[])configurerDirectFieldAccessor.getPropertyValue("templateLoaderPaths")); + } + + @Test + public void contentNegotiatingViewResolution() { + registry.contentNegotiating().useNotAcceptable(false).defaultViews(new MappingJackson2JsonView()); + assertNotNull(registry.getViewResolvers()); + assertEquals(1, registry.getViewResolvers().size()); + assertEquals(ContentNegotiatingViewResolver.class, registry.getViewResolvers().get(0).getClass()); + } + + @Test + public void multipleViewResolutions() { + registry.jsp().and().beanName(); + assertNotNull(registry.getViewResolvers()); + assertEquals(2, registry.getViewResolvers().size()); + } + +} diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportExtensionTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportExtensionTests.java index c17da91504c..a1cc57a3d72 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportExtensionTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportExtensionTests.java @@ -17,6 +17,7 @@ package org.springframework.web.servlet.config.annotation; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import java.util.Arrays; @@ -24,6 +25,7 @@ import java.util.List; import org.junit.Before; import org.junit.Test; import org.springframework.beans.DirectFieldAccessor; +import org.springframework.core.Ordered; import org.springframework.tests.sample.beans.TestBean; import org.springframework.core.convert.converter.Converter; import org.springframework.core.io.FileSystemResourceLoader; @@ -54,8 +56,7 @@ import org.springframework.web.context.support.StaticWebApplicationContext; import org.springframework.web.method.annotation.ModelAttributeMethodProcessor; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.HandlerMethodReturnValueHandler; -import org.springframework.web.servlet.HandlerExceptionResolver; -import org.springframework.web.servlet.HandlerExecutionChain; +import org.springframework.web.servlet.*; import org.springframework.web.servlet.handler.AbstractHandlerMapping; import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor; import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite; @@ -65,12 +66,16 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; import org.springframework.web.servlet.resource.ResourceUrlProviderExposingInterceptor; import org.springframework.web.util.UrlPathHelper; +import org.springframework.web.servlet.view.ContentNegotiatingViewResolver; +import org.springframework.web.servlet.view.InternalResourceViewResolver; +import org.springframework.web.servlet.view.json.MappingJackson2JsonView; /** * A test fixture with a sub-class of {@link WebMvcConfigurationSupport} that * implements the various {@link WebMvcConfigurer} extension points. * * @author Rossen Stoyanchev + * @author Sebastien Deleuze */ public class WebMvcConfigurationSupportExtensionTests { @@ -78,7 +83,6 @@ public class WebMvcConfigurationSupportExtensionTests { private StaticWebApplicationContext webAppContext; - @Before public void setUp() { this.webAppContext = new StaticWebApplicationContext(); @@ -211,6 +215,28 @@ public class WebMvcConfigurationSupportExtensionTests { assertEquals(1, composite.getExceptionResolvers().size()); } + @Test + public void viewResolvers() throws Exception { + ViewResolverComposite viewResolver = webConfig.viewResolverComposite(); + assertEquals(Ordered.LOWEST_PRECEDENCE, viewResolver.getOrder()); + List viewResolvers = viewResolver.getViewResolvers(); + DirectFieldAccessor viewResolverFieldAccessor = new DirectFieldAccessor(viewResolvers.get(0)); + assertEquals(1, viewResolvers.size()); + assertEquals(ContentNegotiatingViewResolver.class, viewResolvers.get(0).getClass()); + assertFalse((Boolean)viewResolverFieldAccessor.getPropertyValue("useNotAcceptableStatusCode")); + List defaultViews = (List)viewResolverFieldAccessor.getPropertyValue("defaultViews"); + assertNotNull(defaultViews); + assertEquals(1, defaultViews.size()); + assertEquals(MappingJackson2JsonView.class, defaultViews.get(0).getClass()); + assertNotNull(viewResolverFieldAccessor.getPropertyValue("contentNegotiationManager")); + viewResolvers = (List)viewResolverFieldAccessor.getPropertyValue("viewResolvers"); + assertNotNull(viewResolvers); + assertEquals(1, viewResolvers.size()); + assertEquals(InternalResourceViewResolver.class, viewResolvers.get(0).getClass()); + viewResolverFieldAccessor = new DirectFieldAccessor(viewResolvers.get(0)); + assertEquals("/", viewResolverFieldAccessor.getPropertyValue("prefix")); + assertEquals(".jsp", viewResolverFieldAccessor.getPropertyValue("suffix")); + } @Controller private static class TestController { @@ -312,6 +338,12 @@ public class WebMvcConfigurationSupportExtensionTests { registry.addViewController("/path"); } + @Override + public void configureViewResolution(ViewResolutionRegistry registry) { + registry.jsp("/", ".jsp"); + registry.contentNegotiating().useNotAcceptable(false).defaultViews(new MappingJackson2JsonView()); + } + @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("src/test/java"); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java index 7d513d08972..f1a0b83027f 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java @@ -22,11 +22,11 @@ import javax.servlet.http.HttpServletRequest; import org.joda.time.DateTime; import org.junit.Before; import org.junit.Test; - import org.springframework.beans.DirectFieldAccessor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Scope; +import org.springframework.core.Ordered; import org.springframework.context.annotation.ScopedProxyMode; import org.springframework.core.convert.ConversionService; import org.springframework.format.annotation.DateTimeFormat; @@ -48,6 +48,8 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon import org.springframework.web.method.support.CompositeUriComponentsContributor; import org.springframework.web.servlet.HandlerExceptionResolver; import org.springframework.web.servlet.HandlerExecutionChain; +import org.springframework.web.servlet.ViewResolver; +import org.springframework.web.servlet.ViewResolverComposite; import org.springframework.web.servlet.handler.AbstractHandlerMapping; import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping; import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor; @@ -69,6 +71,7 @@ import static org.junit.Assert.*; * * @author Rossen Stoyanchev * @author Juergen Hoeller + * @author Sebastien Deleuze */ public class WebMvcConfigurationSupportTests { @@ -199,6 +202,14 @@ public class WebMvcConfigurationSupportTests { assertEquals(1, interceptors.size()); assertEquals(JsonViewResponseBodyAdvice.class, interceptors.get(0).getClass()); } + + @Test + public void viewResolvers() throws Exception { + ViewResolverComposite compositeResolver = this.wac.getBean(ViewResolverComposite.class); + assertEquals(Ordered.LOWEST_PRECEDENCE, compositeResolver.getOrder()); + List viewResolvers = compositeResolver.getViewResolvers(); + assertEquals(0, viewResolvers.size()); + } @Test public void defaultPathMatchConfiguration() throws Exception { 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 new file mode 100644 index 00000000000..3735139a785 --- /dev/null +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating-with-default-values.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + \ 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 new file mode 100644 index 00000000000..5b6c4613470 --- /dev/null +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating.xml @@ -0,0 +1,53 @@ + + + + + + /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-view-resolution.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution.xml new file mode 100644 index 00000000000..f39c3dd89ec --- /dev/null +++ b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolvers.xml b/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolvers.xml deleted file mode 100644 index 827440d5506..00000000000 --- a/spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolvers.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file