Browse Source

Support Java and MVC namespace view resolution config

This commit improves and completes the initial MVC namespace
view resolution implementation. ContentNegotiatingViewResolver
registration is now also supported.

Java Config view resolution support has been added.
FreeMarker, Velocity and Tiles view configurers are registered
depending on the classpath thanks to an ImportSelector.

For both, a default configuration is provided and documented.

Issue: SPR-7093
pull/589/merge
Sebastien Deleuze 12 years ago committed by Rossen Stoyanchev
parent
commit
cc7e8f5558
  1. 26
      spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java
  2. 6
      spring-test/src/test/java/org/springframework/test/web/servlet/samples/spr/EncodedUriTests.java
  3. 100
      spring-webmvc/src/main/java/org/springframework/web/servlet/ViewResolverComposite.java
  4. 6
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java
  5. 252
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolutionBeanDefinitionParser.java
  6. 158
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java
  7. 34
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/BeanNameRegistration.java
  8. 71
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiatingRegistration.java
  9. 5
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java
  10. 5
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java
  11. 59
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerConfigurerConfigurationSupport.java
  12. 94
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerRegistration.java
  13. 40
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/JspRegistration.java
  14. 59
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesConfigurerConfigurationSupport.java
  15. 99
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesRegistration.java
  16. 59
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityConfigurerConfigurationSupport.java
  17. 86
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityRegistration.java
  18. 58
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewConfigurationsImportSelector.java
  19. 48
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistration.java
  20. 164
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistry.java
  21. 66
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java
  22. 5
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java
  23. 8
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java
  24. 7
      spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java
  25. 28
      spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.0.xsd
  26. 216
      spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.1.xsd
  27. 100
      spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java
  28. 205
      spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistryTests.java
  29. 38
      spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportExtensionTests.java
  30. 13
      spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java
  31. 26
      spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating-with-default-values.xml
  32. 53
      spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating.xml
  33. 26
      spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution.xml
  34. 16
      spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolvers.xml

26
spring-test/src/test/java/org/springframework/test/web/servlet/samples/context/JavaConfigTests.java

@ -1,5 +1,5 @@ @@ -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 @@ -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.*; @@ -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 { @@ -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;
}
}
}

6
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; @@ -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 { @@ -94,6 +95,11 @@ public class EncodedUriTests {
public HandlerMappingConfigurer myHandlerMappingConfigurer() {
return new HandlerMappingConfigurer();
}
@Override
public void configureViewResolution(ViewResolutionRegistry registry) {
registry.jsp("", "");
}
}
@Controller

100
spring-webmvc/src/main/java/org/springframework/web/servlet/ViewResolverComposite.java

@ -0,0 +1,100 @@ @@ -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<ViewResolver> 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<ViewResolver> viewResolvers) {
this.viewResolvers = viewResolvers;
}
/**
* Return the list of view viewResolvers to delegate to.
*/
public List<ViewResolver> 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);
}
}
}
}
}

6
spring-webmvc/src/main/java/org/springframework/web/servlet/config/MvcNamespaceHandler.java

@ -1,5 +1,5 @@ @@ -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; @@ -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());
}
}

252
spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolutionBeanDefinitionParser.java

@ -0,0 +1,252 @@ @@ -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<Element> viewResolverElements =
DomUtils.getChildElementsByTagName(element, new String[] { "jsp", "tiles", "bean-name", "freemarker", "velocity", "bean", "ref" });
ManagedList<Object> viewResolvers = new ManagedList<Object>();
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<String,Object> 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<Object> viewResolvers) {
Map<String, Object> propertyMap = new HashMap<String, Object>();
ManagedList<Object> defaultViewBeanDefinitions = new ManagedList<Object>();
List<Element> 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<String, Object> propertyMap = new HashMap<String, Object>();
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<String, Object> propertyMap = new HashMap<String, Object>();
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<String, Object> propertyMap = new HashMap<String, Object>();
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<String, Object> propertyMap = new HashMap<String, Object>();
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<String, Object> propertyMap = new HashMap<String, Object>();
propertyMap.put("order", order);
return registerBean(propertyMap, BeanNameViewResolver.class, parserContext);
}
private BeanDefinition registerTilesConfigurerBean(Element viewResolverElement, ParserContext parserContext) {
Map<String, Object> propertyMap = new HashMap<String, Object>();
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<String, Object> propertyMap = new HashMap<String, Object>();
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<String, Object> propertyMap = new HashMap<String, Object>();
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);
}
}

158
spring-webmvc/src/main/java/org/springframework/web/servlet/config/ViewResolversBeanDefinitionParser.java

@ -1,158 +0,0 @@ @@ -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<Element> 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<String,Object> 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<String, Object> propertyMap= new HashMap<String, Object>();
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<String, Object> propertyMap= new HashMap<String, Object>();
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<String, Object> propertyMap= new HashMap<String, Object>();
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<String, Object> propertyMap= new HashMap<String, Object>();
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<String, Object> propertyMap= new HashMap<String, Object>();
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<String, Object> propertyMap= new HashMap<String, Object>();
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);
}
}
}

34
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/BeanNameRegistration.java

@ -0,0 +1,34 @@ @@ -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<BeanNameViewResolver> {
public BeanNameRegistration(ViewResolutionRegistry registry) {
super(registry, new BeanNameViewResolver());
}
}

71
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ContentNegotiatingRegistration.java

@ -0,0 +1,71 @@ @@ -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<ContentNegotiatingViewResolver> {
private List<View> 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<View>();
}
this.defaultViews.addAll(Arrays.asList(defaultViews));
return this;
}
@Override
protected ContentNegotiatingViewResolver getViewResolver() {
this.viewResolver.setDefaultViews(this.defaultViews);
return super.getViewResolver();
}
}

5
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java

@ -75,6 +75,11 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport { @@ -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);

5
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java

@ -1,5 +1,5 @@ @@ -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; @@ -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 {
}

59
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerConfigurerConfigurationSupport.java

@ -0,0 +1,59 @@ @@ -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<WebMvcConfigurationSupport> webMvcConfigurationSupports;
@Autowired(required = false)
public void setWebMvcConfigurationSupports(List<WebMvcConfigurationSupport> 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;
}
}

94
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/FreeMarkerRegistration.java

@ -0,0 +1,94 @@ @@ -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<FreeMarkerViewResolver> {
private final FreeMarkerConfigurer configurer;
private List<String> 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;
}
}

40
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/JspRegistration.java

@ -0,0 +1,40 @@ @@ -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<InternalResourceViewResolver> {
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);
}
}

59
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesConfigurerConfigurationSupport.java

@ -0,0 +1,59 @@ @@ -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<WebMvcConfigurationSupport> webMvcConfigurationSupports;
@Autowired(required = false)
public void setWebMvcConfigurationSupports(List<WebMvcConfigurationSupport> 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;
}
}

99
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/TilesRegistration.java

@ -0,0 +1,99 @@ @@ -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<TilesViewResolver> {
private List<String> 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<String>();
}
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;
}
}

59
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityConfigurerConfigurationSupport.java

@ -0,0 +1,59 @@ @@ -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<WebMvcConfigurationSupport> webMvcConfigurationSupports;
@Autowired(required = false)
public void setWebMvcConfigurationSupports(List<WebMvcConfigurationSupport> 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;
}
}

86
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/VelocityRegistration.java

@ -0,0 +1,86 @@ @@ -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<VelocityViewResolver> {
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;
}
}

58
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewConfigurationsImportSelector.java

@ -0,0 +1,58 @@ @@ -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<String> configurationClasses = new ArrayList<String>();
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]);
}
}

48
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistration.java

@ -0,0 +1,48 @@ @@ -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<T extends ViewResolver> {
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;
}
}

164
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistry.java

@ -0,0 +1,164 @@ @@ -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<ViewResolutionRegistration<?>> registrations = new ArrayList<ViewResolutionRegistration<?>>();
/**
* Register a custom {@link ViewResolver} bean.
*/
public ViewResolutionRegistration<ViewResolver> addViewResolver(ViewResolver viewResolver) {
ViewResolutionRegistration<ViewResolver> registration = new ViewResolutionRegistration<ViewResolver>(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<ViewResolver> getViewResolvers() {
List<ViewResolver> viewResolvers = new ArrayList<ViewResolver>();
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);
}
}

66
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java

@ -64,9 +64,7 @@ import org.springframework.web.context.ServletContextAware; @@ -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; @@ -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; @@ -150,12 +149,25 @@ import org.springframework.web.util.UrlPathHelper;
* libraries available on the classpath.
* </ul>
*
* <p>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 @@ -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 @@ -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 @@ -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<ViewResolver> viewResolvers = registry.getViewResolvers();
ContentNegotiatingViewResolver contentNegotiatingViewResolver = null;
List<ViewResolver> filteredViewResolvers = new ArrayList<ViewResolver>();
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<ViewResolver>();
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

5
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java

@ -138,6 +138,11 @@ public interface WebMvcConfigurer { @@ -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,

8
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java

@ -133,6 +133,14 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer { @@ -133,6 +133,14 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
public void addViewControllers(ViewControllerRegistry registry) {
}
/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void configureViewResolution(ViewResolutionRegistry registry) {
}
/**
* {@inheritDoc}
* <p>This implementation is empty.

7
spring-webmvc/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java

@ -113,6 +113,13 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer { @@ -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) {

28
spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.0.xsd

@ -515,33 +515,5 @@ @@ -515,33 +515,5 @@
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:element name="view-resolvers" >
<xsd:complexType>
<xsd:all minOccurs="0">
<xsd:element name="jsp" minOccurs="0" >
<xsd:complexType>
<xsd:attribute name="prefix" />
<xsd:attribute name="suffix" />
</xsd:complexType>
</xsd:element>
<xsd:element name="tiles" minOccurs="0" >
<xsd:complexType>
<xsd:attribute name="definitions" />
<xsd:attribute name="viewClass" use="optional" />
</xsd:complexType>
</xsd:element>
<xsd:element name="bean-name" minOccurs="0" />
<xsd:element name="freemarker" minOccurs="0">
<xsd:complexType>
<xsd:attribute name="prefix" />
<xsd:attribute name="suffix" />
<xsd:attribute name="templateLoaderPath" />
</xsd:complexType>
</xsd:element>
</xsd:all>
</xsd:complexType>
</xsd:element>
</xsd:schema>

216
spring-webmvc/src/main/resources/org/springframework/web/servlet/config/spring-mvc-4.1.xsd

@ -598,5 +598,221 @@ @@ -598,5 +598,221 @@
</xsd:attribute>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="jsp-type">
<xsd:attribute name="prefix" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The prefix that gets prepended to view names when building a URL.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="suffix" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The suffix that gets appended to view names when building a URL.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="tiles-type">
<xsd:attribute name="definitions" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The Tiles definitions, i.e. a single value or a comma separated list of files containing the definitions.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="check-refresh" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Set whether to check Tiles definition files for a refresh at runtime.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="bean-name-type" />
<xsd:complexType name="freemarker-type">
<xsd:attribute name="prefix" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Set the prefix that gets prepended to view names when building a URL.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="suffix" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Set the suffix that gets appended to view names when building a URL.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Enable or disable caching.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="template-loader-paths" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Set a List of TemplateLoaders that will be used to search for templates.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:complexType name="velocity-type">
<xsd:attribute name="prefix" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Set the prefix that gets prepended to view names when building a URL.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="suffix" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Set the suffix that gets appended to view names when building a URL.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="cache" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Enable or disable caching.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="resource-loader-path" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Set the Velocity resource loader path via a Spring resource location.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<xsd:element name="view-resolution">
<xsd:annotation>
<xsd:documentation><![CDATA[
Helps with configuring a list of view resolvers.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:sequence minOccurs="0">
<xsd:choice maxOccurs="unbounded">
<xsd:element name="content-negotiating" type="content-negotiating-type" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
Register a ContentNegotiatingViewResolver bean.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="jsp" type="jsp-type" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
Register an InternalResourceViewResolver bean.
Default configuration is "/WEB-INF/" prefix and ".jsp" suffix
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="tiles" type="tiles-type" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
Register a TilesViewResolver and a TilesConfigurer with default "/WEB-INF/tiles.xml"
definition and no Tiles definition check refresh.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="bean-name" type="bean-name-type" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
Register a BeanNameViewResolver bean.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="freemarker" type="freemarker-type" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
Register a FreeMarkerViewResolver and a FreeMarkerConfigurer beans with "" prefix,
".ftl" suffix and "/WEB-INF/" templateLoaderPath.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="velocity" type="velocity-type" maxOccurs="1">
<xsd:annotation>
<xsd:documentation><![CDATA[
Register a VelocityLayoutViewResolver and a VelocityConfigurer beans with default ""
prefix, ".vm" suffix and "/WEB-INF/" resourceLoaderPath.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element ref="beans:bean">
<xsd:annotation>
<xsd:documentation><![CDATA[
A bean definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element ref="beans:ref">
<xsd:annotation>
<xsd:documentation><![CDATA[
A reference to a bean.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:complexType name="content-negotiating-type">
<xsd:all>
<xsd:element name="default-views" minOccurs="0">
<xsd:complexType>
<xsd:sequence>
<xsd:choice maxOccurs="unbounded">
<xsd:element ref="beans:bean">
<xsd:annotation>
<xsd:documentation><![CDATA[
A bean definition.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element ref="beans:ref">
<xsd:annotation>
<xsd:documentation><![CDATA[
A reference to a bean.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
</xsd:choice>
</xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:all>
<xsd:attribute name="manager" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The bean name of the ContentNegotiationManager implementation to use for determining
the requested MediaType media types of a request.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="use-not-acceptable" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicate whether a 406 Not Acceptable status code should be returned if no suitable
view can be found.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:schema>

100
spring-webmvc/src/test/java/org/springframework/web/servlet/config/MvcNamespaceTests.java

@ -51,7 +51,7 @@ import org.springframework.validation.Errors; @@ -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; @@ -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.*; @@ -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 { @@ -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);

205
spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/ViewResolutionRegistryTests.java

@ -0,0 +1,205 @@ @@ -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());
}
}

38
spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportExtensionTests.java

@ -17,6 +17,7 @@ @@ -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; @@ -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; @@ -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 @@ -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 { @@ -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 { @@ -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<ViewResolver> 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<View> defaultViews = (List<View>)viewResolverFieldAccessor.getPropertyValue("defaultViews");
assertNotNull(defaultViews);
assertEquals(1, defaultViews.size());
assertEquals(MappingJackson2JsonView.class, defaultViews.get(0).getClass());
assertNotNull(viewResolverFieldAccessor.getPropertyValue("contentNegotiationManager"));
viewResolvers = (List<ViewResolver>)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 { @@ -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");

13
spring-webmvc/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java

@ -22,11 +22,11 @@ import javax.servlet.http.HttpServletRequest; @@ -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 @@ -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.*; @@ -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 { @@ -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<ViewResolver> viewResolvers = compositeResolver.getViewResolvers();
assertEquals(0, viewResolvers.size());
}
@Test
public void defaultPathMatchConfiguration() throws Exception {

26
spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating-with-default-values.xml

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<mvc:annotation-driven />
<mvc:view-resolution>
<mvc:content-negotiating use-not-acceptable="true">
<mvc:default-views>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
</mvc:default-views>
</mvc:content-negotiating>
<mvc:jsp />
<mvc:freemarker />
<mvc:velocity />
</mvc:view-resolution>
</beans>

53
spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-content-negotiating.xml

@ -0,0 +1,53 @@ @@ -0,0 +1,53 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="myViewResolver2"
class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="mediaTypes">
<value>
xml=application/rss+xml
</value>
</property>
</bean>
<mvc:view-resolution>
<mvc:content-negotiating manager="contentNegotiationManager" use-not-acceptable="true">
<mvc:default-views>
<bean class="org.springframework.web.servlet.view.json.MappingJackson2JsonView" />
</mvc:default-views>
</mvc:content-negotiating>
<mvc:jsp prefix="/WEB-INF/" suffix=".jsp" />
<mvc:bean-name />
<mvc:tiles definitions="/org/springframework/web/servlet/resource/tiles/tiles1.xml" />
<mvc:freemarker prefix="" suffix=".ftl" template-loader-paths="/" />
<mvc:velocity prefix="" suffix=".vm" resource-loader-path="/" />
<bean id="myViewResolver1" class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<ref bean="myViewResolver2" />
</mvc:view-resolution>
</beans>

26
spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolution.xml

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<mvc:view-resolution>
<mvc:jsp prefix="/WEB-INF/" suffix=".jsp" />
<mvc:bean-name />
<mvc:tiles definitions="/org/springframework/web/servlet/resource/tiles/tiles1.xml,/org/springframework/web/servlet/resource/tiles/tiles2.xml"
check-refresh="true" />
<mvc:freemarker prefix="" suffix=".ftl"
template-loader-paths="/,/test" cache="false" />
<mvc:velocity prefix="" suffix=".vm"
resource-loader-path="/" cache="false" />
</mvc:view-resolution>
</beans>

16
spring-webmvc/src/test/resources/org/springframework/web/servlet/config/mvc-config-view-resolvers.xml

@ -1,16 +0,0 @@ @@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<mvc:view-resolvers>
<mvc:jsp prefix="/WEB-INF/" suffix=".jsp" />
<mvc:bean-name />
<mvc:tiles definitions="/org/springframework/web/servlet/resource/tiles/tiles1.xml,/org/springframework/web/servlet/resource/tiles/tiles2.xml" />
<mvc:freemarker prefix="" suffix=".ftl" templateLoaderPath="/" />
</mvc:view-resolvers>
</beans>
Loading…
Cancel
Save