Polish view controller MVC config

This commit is contained in:
Rossen Stoyanchev
2014-07-17 11:23:45 -04:00
parent 61ec8fd236
commit 7f7fd7d311
5 changed files with 81 additions and 74 deletions

View File

@@ -19,7 +19,6 @@ package org.springframework.web.servlet.config;
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.support.ManagedMap;
import org.springframework.beans.factory.support.RootBeanDefinition;
@@ -36,6 +35,7 @@ import org.w3c.dom.Element;
*
* @author Keith Donald
* @author Christian Dupuis
* @author Rossen Stoyanchev
* @since 3.0
*/
class ViewControllerBeanDefinitionParser implements BeanDefinitionParser {
@@ -50,48 +50,45 @@ class ViewControllerBeanDefinitionParser implements BeanDefinitionParser {
Object source = parserContext.extractSource(element);
// Register SimpleUrlHandlerMapping for view controllers
BeanDefinition handlerMappingDef = registerHandlerMapping(parserContext, source);
BeanDefinition handlerMapping = registerHandlerMapping(parserContext, source);
// Ensure BeanNameUrlHandlerMapping (SPR-8289) and default HandlerAdapters are not "turned off"
MvcNamespaceUtils.registerDefaultComponents(parserContext, source);
// Create view controller bean definition
RootBeanDefinition viewControllerDef = new RootBeanDefinition(ParameterizableViewController.class);
viewControllerDef.setSource(source);
RootBeanDefinition controller = new RootBeanDefinition(ParameterizableViewController.class);
controller.setSource(source);
if (element.hasAttribute("view-name")) {
viewControllerDef.getPropertyValues().add("viewName", element.getAttribute("view-name"));
controller.getPropertyValues().add("viewName", element.getAttribute("view-name"));
}
Map<String, BeanDefinition> urlMap;
if (handlerMappingDef.getPropertyValues().contains("urlMap")) {
urlMap = (Map<String, BeanDefinition>) handlerMappingDef.getPropertyValues().getPropertyValue("urlMap").getValue();
if (handlerMapping.getPropertyValues().contains("urlMap")) {
urlMap = (Map<String, BeanDefinition>) handlerMapping.getPropertyValues().getPropertyValue("urlMap").getValue();
}
else {
urlMap = new ManagedMap<String, BeanDefinition>();
handlerMappingDef.getPropertyValues().add("urlMap", urlMap);
handlerMapping.getPropertyValues().add("urlMap", urlMap);
}
urlMap.put(element.getAttribute("path"), viewControllerDef);
urlMap.put(element.getAttribute("path"), controller);
return null;
}
private BeanDefinition registerHandlerMapping(ParserContext parserContext, Object source) {
if (!parserContext.getRegistry().containsBeanDefinition(HANDLER_MAPPING_BEAN_NAME)) {
RuntimeBeanReference pathMatcherRef = MvcNamespaceUtils.registerPathMatcher(null, parserContext, source);
RuntimeBeanReference pathHelperRef = MvcNamespaceUtils.registerUrlPathHelper(null, parserContext, source);
RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
handlerMappingDef.setSource(source);
handlerMappingDef.getPropertyValues().add("order", "1");
handlerMappingDef.getPropertyValues().add("pathMatcher", pathMatcherRef).add("urlPathHelper", pathHelperRef);
handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
parserContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef);
parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, HANDLER_MAPPING_BEAN_NAME));
return handlerMappingDef;
}
else {
return parserContext.getRegistry().getBeanDefinition(HANDLER_MAPPING_BEAN_NAME);
private BeanDefinition registerHandlerMapping(ParserContext context, Object source) {
if (context.getRegistry().containsBeanDefinition(HANDLER_MAPPING_BEAN_NAME)) {
return context.getRegistry().getBeanDefinition(HANDLER_MAPPING_BEAN_NAME);
}
RootBeanDefinition beanDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
beanDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
context.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, beanDef);
context.registerComponent(new BeanComponentDefinition(beanDef, HANDLER_MAPPING_BEAN_NAME));
beanDef.setSource(source);
beanDef.getPropertyValues().add("order", "1");
beanDef.getPropertyValues().add("pathMatcher", MvcNamespaceUtils.registerPathMatcher(null, context, source));
beanDef.getPropertyValues().add("urlPathHelper", MvcNamespaceUtils.registerUrlPathHelper(null, context, source));
return beanDef;
}
}

View File

@@ -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.
@@ -21,7 +21,7 @@ import org.springframework.web.servlet.RequestToViewNameTranslator;
import org.springframework.web.servlet.mvc.ParameterizableViewController;
/**
* Encapsulates information required to create a view controller.
* Assist with the registration of a single view controller.
*
* @author Rossen Stoyanchev
* @author Keith Donald
@@ -33,37 +33,38 @@ public class ViewControllerRegistration {
private String viewName;
/**
* Creates a {@link ViewControllerRegistration} with the given URL path. When a request matches
* to the given URL path this view controller will process it.
* Creates a registration for the given URL path (or path pattern).
*/
public ViewControllerRegistration(String urlPath) {
Assert.notNull(urlPath, "A URL path is required to create a view controller.");
Assert.notNull(urlPath, "'urlPath' is required.");
this.urlPath = urlPath;
}
/**
* Sets the view name to use for this view controller. This field is optional. If not specified the
* view controller will return a {@code null} view name, which will be resolved through the configured
* {@link RequestToViewNameTranslator}. By default that means "/foo/bar" would resolve to "foo/bar".
* Set the view name to return.
*
* <p>If not specified, the view controller returns {@code null} as the view
* name in which case the configured {@link RequestToViewNameTranslator}
* selects the view. In effect {@code DefaultRequestToViewNameTranslator}
* translates "/foo/bar" to "foo/bar".
*
* @see org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
*/
public void setViewName(String viewName) {
this.viewName = viewName;
}
/**
* Returns the URL path for the view controller.
*/
protected String getUrlPath() {
return urlPath;
return this.urlPath;
}
/**
* Returns the view controllers.
*/
protected Object getViewController() {
ParameterizableViewController controller = new ParameterizableViewController();
controller.setViewName(viewName);
controller.setViewName(this.viewName);
return controller;
}

View File

@@ -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.
@@ -26,9 +26,9 @@ import org.springframework.web.servlet.handler.AbstractHandlerMapping;
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
/**
* Stores registrations of view controllers. A view controller does nothing more than return a specified
* view name. It saves you from having to write a controller when you want to forward the request straight
* through to a view such as a JSP.
* Enables the registration of view controllers that have no logic other than to
* return the view name they're configured with. This is an alternative to
* writing a controller manually to do the same.
*
* @author Rossen Stoyanchev
* @author Keith Donald
@@ -40,36 +40,41 @@ public class ViewControllerRegistry {
private int order = 1;
/**
* Register a view controller mapped to the given URL path or URL path pattern.
*/
public ViewControllerRegistration addViewController(String urlPath) {
ViewControllerRegistration registration = new ViewControllerRegistration(urlPath);
registrations.add(registration);
this.registrations.add(registration);
return registration;
}
/**
* Specify the order to use for ViewControllers mappings relative to other {@link HandlerMapping}s
* configured in the Spring MVC application context. The default value for view controllers is 1,
* which is 1 higher than the value used for annotated controllers.
* Specify the order to use for the {@code HandlerMapping} used to map view
* controllers relative to other handler mappings configured in Spring MVC.
* <p>By default this is set to 1, i.e. right after annotated controllers,
* which are ordered at 0.
*/
public void setOrder(int order) {
this.order = order;
}
/**
* Returns a handler mapping with the mapped ViewControllers; or {@code null} in case of no registrations.
* Return the {@code HandlerMapping} that contains the registered view
* controller mappings, or {@code null} for no registrations.
*/
protected AbstractHandlerMapping getHandlerMapping() {
if (registrations.isEmpty()) {
if (this.registrations.isEmpty()) {
return null;
}
Map<String, Object> urlMap = new LinkedHashMap<String, Object>();
for (ViewControllerRegistration registration : registrations) {
for (ViewControllerRegistration registration : this.registrations) {
urlMap.put(registration.getUrlPath(), registration.getViewController());
}
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
handlerMapping.setOrder(order);
handlerMapping.setOrder(this.order);
handlerMapping.setUrlMap(urlMap);
return handlerMapping;
}