Add method to allow further validation of request mapping infos at startup + other minor javadoc updates.
git-svn-id: https://src.springframework.org/svn/spring-framework/trunk@4297 50f2f4bb-b051-0410-bef5-90022cba6387
This commit is contained in:
parent
26a0e223a4
commit
416c282609
|
|
@ -59,7 +59,6 @@ import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
|
||||||
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
|
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
|
||||||
import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite;
|
import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite;
|
||||||
import org.springframework.web.servlet.handler.MappedInterceptor;
|
import org.springframework.web.servlet.handler.MappedInterceptor;
|
||||||
import org.springframework.web.servlet.handler.MappedInterceptors;
|
|
||||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||||
import org.springframework.web.servlet.mvc.Controller;
|
import org.springframework.web.servlet.mvc.Controller;
|
||||||
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||||
|
|
@ -88,7 +87,7 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* <p><strong>Note:</strong> that the SimpleUrlHandlerMapping instances above will have empty URL maps and
|
* <p><strong>Note:</strong> that the SimpleUrlHandlerMapping instances above will have empty URL maps and
|
||||||
* hence no effect until explicitly configured via {@link WebMvcConfigurer}.
|
* hence no effect until explicitly configured via one of the {@link WebMvcConfigurer} callbacks.
|
||||||
*
|
*
|
||||||
* <p>Registers these handler adapters:
|
* <p>Registers these handler adapters:
|
||||||
* <ul>
|
* <ul>
|
||||||
|
|
@ -108,7 +107,6 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>{@link FormattingConversionService} for use with annotated controller methods and the spring:eval JSP tag.
|
* <li>{@link FormattingConversionService} for use with annotated controller methods and the spring:eval JSP tag.
|
||||||
* <li>{@link Validator} for validating model attributes on annotated controller methods.
|
* <li>{@link Validator} for validating model attributes on annotated controller methods.
|
||||||
* <li>{@link MappedInterceptors} containing a list Spring MVC lifecycle interceptors.
|
|
||||||
* </ul>
|
* </ul>
|
||||||
*
|
*
|
||||||
* @see EnableWebMvc
|
* @see EnableWebMvc
|
||||||
|
|
@ -128,7 +126,7 @@ class WebMvcConfiguration implements ApplicationContextAware, ServletContextAwar
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
public void setConfigurers(List<WebMvcConfigurer> configurers) {
|
public void setConfigurers(List<WebMvcConfigurer> configurers) {
|
||||||
this.configurers.addConfigurers(configurers);
|
this.configurers.addWebMvcConfigurers(configurers);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setServletContext(ServletContext servletContext) {
|
public void setServletContext(ServletContext servletContext) {
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ public interface WebMvcConfigurer {
|
||||||
/**
|
/**
|
||||||
* Add {@link Converter}s and {@link Formatter}s in addition to the ones registered by default.
|
* Add {@link Converter}s and {@link Formatter}s in addition to the ones registered by default.
|
||||||
*/
|
*/
|
||||||
void addFormatters(FormatterRegistry formatterRegistry);
|
void addFormatters(FormatterRegistry registry);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the list of {@link HttpMessageConverter}s to use when resolving method arguments or handling
|
* Configure the list of {@link HttpMessageConverter}s to use when resolving method arguments or handling
|
||||||
|
|
@ -102,20 +102,20 @@ public interface WebMvcConfigurer {
|
||||||
* invocation. Interceptors can be registered to apply to all requests or limited to a set of path patterns.
|
* invocation. Interceptors can be registered to apply to all requests or limited to a set of path patterns.
|
||||||
* @see InterceptorConfigurer
|
* @see InterceptorConfigurer
|
||||||
*/
|
*/
|
||||||
void configureInterceptors(InterceptorConfigurer interceptorConfigurer);
|
void configureInterceptors(InterceptorConfigurer configurer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure the view controllers to use. A view controller is used to map a URL path directly to a view name.
|
* Configure the view controllers to use. A view controller is used to map a URL path directly to a view name.
|
||||||
* This is convenient when a request does not require controller logic.
|
* This is convenient when a request does not require controller logic.
|
||||||
*/
|
*/
|
||||||
void configureViewControllers(ViewControllerConfigurer viewControllerConfigurer);
|
void configureViewControllers(ViewControllerConfigurer configurer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure a handler for serving static resources such as images, js, and, css files through Spring MVC
|
* Configure a handler for serving static resources such as images, js, and, css files through Spring MVC
|
||||||
* including setting cache headers optimized for efficient loading in a web browser. Resources can be served
|
* including setting cache headers optimized for efficient loading in a web browser. Resources can be served
|
||||||
* out of locations under web application root, from the classpath, and others.
|
* out of locations under web application root, from the classpath, and others.
|
||||||
*/
|
*/
|
||||||
void configureResourceHandling(ResourceConfigurer resourceConfigurer);
|
void configureResourceHandling(ResourceConfigurer configurer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Configure a handler for delegating unhandled requests by forwarding to the Servlet container's default
|
* Configure a handler for delegating unhandled requests by forwarding to the Servlet container's default
|
||||||
|
|
@ -123,6 +123,6 @@ public interface WebMvcConfigurer {
|
||||||
* cleaner URLs (without a servlet prefix) but may need to still allow some requests (e.g. static resources)
|
* cleaner URLs (without a servlet prefix) but may need to still allow some requests (e.g. static resources)
|
||||||
* to be handled by the Servlet container's default servlet.
|
* to be handled by the Servlet container's default servlet.
|
||||||
*/
|
*/
|
||||||
void configureDefaultServletHandling(DefaultServletHandlerConfigurer handlerConfigurer);
|
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,7 +38,7 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* <p>This implementation is empty.
|
* <p>This implementation is empty.
|
||||||
*/
|
*/
|
||||||
public void addFormatters(FormatterRegistry formatterRegistry) {
|
public void addFormatters(FormatterRegistry registry) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -81,28 +81,28 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* <p>This implementation is empty.
|
* <p>This implementation is empty.
|
||||||
*/
|
*/
|
||||||
public void configureInterceptors(InterceptorConfigurer interceptorConfigurer) {
|
public void configureInterceptors(InterceptorConfigurer configurer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* <p>This implementation is empty.
|
* <p>This implementation is empty.
|
||||||
*/
|
*/
|
||||||
public void configureViewControllers(ViewControllerConfigurer viewControllerConfigurer) {
|
public void configureViewControllers(ViewControllerConfigurer configurer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* <p>This implementation is empty.
|
* <p>This implementation is empty.
|
||||||
*/
|
*/
|
||||||
public void configureResourceHandling(ResourceConfigurer resourceConfigurer) {
|
public void configureResourceHandling(ResourceConfigurer configurer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* <p>This implementation is empty.
|
* <p>This implementation is empty.
|
||||||
*/
|
*/
|
||||||
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer handlerConfigurer) {
|
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -36,74 +36,74 @@ import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||||
*/
|
*/
|
||||||
class WebMvcConfigurerComposite implements WebMvcConfigurer {
|
class WebMvcConfigurerComposite implements WebMvcConfigurer {
|
||||||
|
|
||||||
private final List<WebMvcConfigurer> configurers = new ArrayList<WebMvcConfigurer>();
|
private final List<WebMvcConfigurer> delegates = new ArrayList<WebMvcConfigurer>();
|
||||||
|
|
||||||
public void addConfigurers(List<WebMvcConfigurer> configurers) {
|
public void addWebMvcConfigurers(List<WebMvcConfigurer> configurers) {
|
||||||
if (configurers != null) {
|
if (configurers != null) {
|
||||||
this.configurers.addAll(configurers);
|
this.delegates.addAll(configurers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addFormatters(FormatterRegistry formatterRegistry) {
|
public void addFormatters(FormatterRegistry registry) {
|
||||||
for (WebMvcConfigurer configurer : configurers) {
|
for (WebMvcConfigurer delegate : delegates) {
|
||||||
configurer.addFormatters(formatterRegistry);
|
delegate.addFormatters(registry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
for (WebMvcConfigurer configurer : configurers) {
|
for (WebMvcConfigurer delegate : delegates) {
|
||||||
configurer.configureMessageConverters(converters);
|
delegate.configureMessageConverters(converters);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||||
for (WebMvcConfigurer configurer : configurers) {
|
for (WebMvcConfigurer delegate : delegates) {
|
||||||
configurer.addArgumentResolvers(argumentResolvers);
|
delegate.addArgumentResolvers(argumentResolvers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
||||||
for (WebMvcConfigurer configurer : configurers) {
|
for (WebMvcConfigurer delegate : delegates) {
|
||||||
configurer.addReturnValueHandlers(returnValueHandlers);
|
delegate.addReturnValueHandlers(returnValueHandlers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||||
for (WebMvcConfigurer configurer : configurers) {
|
for (WebMvcConfigurer delegate : delegates) {
|
||||||
configurer.configureHandlerExceptionResolvers(exceptionResolvers);
|
delegate.configureHandlerExceptionResolvers(exceptionResolvers);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configureInterceptors(InterceptorConfigurer interceptorRegistry) {
|
public void configureInterceptors(InterceptorConfigurer configurer) {
|
||||||
for (WebMvcConfigurer configurer : configurers) {
|
for (WebMvcConfigurer delegate : delegates) {
|
||||||
configurer.configureInterceptors(interceptorRegistry);
|
delegate.configureInterceptors(configurer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configureViewControllers(ViewControllerConfigurer viewControllerConfigurer) {
|
public void configureViewControllers(ViewControllerConfigurer configurer) {
|
||||||
for (WebMvcConfigurer configurer : configurers) {
|
for (WebMvcConfigurer delegate : delegates) {
|
||||||
configurer.configureViewControllers(viewControllerConfigurer);
|
delegate.configureViewControllers(configurer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configureResourceHandling(ResourceConfigurer resourceConfigurer) {
|
public void configureResourceHandling(ResourceConfigurer configurer) {
|
||||||
for (WebMvcConfigurer configurer : configurers) {
|
for (WebMvcConfigurer delegate : delegates) {
|
||||||
configurer.configureResourceHandling(resourceConfigurer);
|
delegate.configureResourceHandling(configurer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer handlerConfigurer) {
|
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
|
||||||
for (WebMvcConfigurer configurer : configurers) {
|
for (WebMvcConfigurer delegate : delegates) {
|
||||||
configurer.configureDefaultServletHandling(handlerConfigurer);
|
delegate.configureDefaultServletHandling(configurer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Validator getValidator() {
|
public Validator getValidator() {
|
||||||
Map<WebMvcConfigurer, Validator> validators = new HashMap<WebMvcConfigurer, Validator>();
|
Map<WebMvcConfigurer, Validator> validators = new HashMap<WebMvcConfigurer, Validator>();
|
||||||
for (WebMvcConfigurer configurer : configurers) {
|
for (WebMvcConfigurer delegate : delegates) {
|
||||||
Validator validator = configurer.getValidator();
|
Validator validator = delegate.getValidator();
|
||||||
if (validator != null) {
|
if (validator != null) {
|
||||||
validators.put(configurer, validator);
|
validators.put(delegate, validator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (validators.size() == 0) {
|
if (validators.size() == 0) {
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
||||||
detectHandlerMethods(beanName);
|
detectHandlerMethods(beanName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
handlerMethodsInitialized(getHandlerMethods());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -136,6 +137,13 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
||||||
*/
|
*/
|
||||||
protected abstract boolean isHandler(Class<?> beanType);
|
protected abstract boolean isHandler(Class<?> beanType);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked after all handler methods found in beans of the current ApplicationContext have been registered.
|
||||||
|
* @param handlerMethods a read-only map with mapping conditions (generic type {@code <T>}) and HandlerMethods.
|
||||||
|
*/
|
||||||
|
protected void handlerMethodsInitialized(Map<T, HandlerMethod> handlerMethods) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Detect and register handler methods for the specified handler.
|
* Detect and register handler methods for the specified handler.
|
||||||
* @param handler the bean name of a handler or a handler instance
|
* @param handler the bean name of a handler or a handler instance
|
||||||
|
|
|
||||||
|
|
@ -171,8 +171,10 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set one or more custom argument resolvers to use with {@link RequestMapping}, {@link ModelAttribute}, and
|
* Set one or more custom argument resolvers to use with {@link RequestMapping}, {@link ModelAttribute}, and
|
||||||
* {@link InitBinder} methods. Custom argument resolvers are given a chance to resolve argument values
|
* {@link InitBinder} methods.
|
||||||
* ahead of the standard argument resolvers registered by default.
|
* <p>Generally custom argument resolvers are invoked first. However this excludes
|
||||||
|
* default argument resolvers that rely on the presence of annotations (e.g. {@code @RequestParameter},
|
||||||
|
* {@code @PathVariable}, etc.) Those resolvers can only be customized via {@link #setArgumentResolvers(List)}
|
||||||
* <p>An existing {@link WebArgumentResolver} can either adapted with {@link ServletWebArgumentResolverAdapter}
|
* <p>An existing {@link WebArgumentResolver} can either adapted with {@link ServletWebArgumentResolverAdapter}
|
||||||
* or preferably converted to a {@link HandlerMethodArgumentResolver} instead.
|
* or preferably converted to a {@link HandlerMethodArgumentResolver} instead.
|
||||||
*/
|
*/
|
||||||
|
|
@ -208,8 +210,9 @@ public class RequestMappingHandlerAdapter extends AbstractHandlerMethodAdapter i
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set custom return value handlers to use to handle the return values of {@link RequestMapping} methods.
|
* Set custom return value handlers to use to handle the return values of {@link RequestMapping} methods.
|
||||||
* Custom return value handlers are given a chance to handle a return value before the standard
|
* <p>Generally custom return value handlers are invoked first. However this excludes default return value
|
||||||
* return value handlers registered by default.
|
* handlers that rely on the presence of annotations like {@code @ResponseBody}, {@code @ModelAttribute},
|
||||||
|
* and others. Those handlers can only be customized via {@link #setReturnValueHandlers(List)}.
|
||||||
* @param returnValueHandlers custom return value handlers for {@link RequestMapping} methods
|
* @param returnValueHandlers custom return value handlers for {@link RequestMapping} methods
|
||||||
*/
|
*/
|
||||||
public void setCustomReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
public void setCustomReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
package org.springframework.web.servlet.mvc.method.annotation;
|
package org.springframework.web.servlet.mvc.method.annotation;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
|
@ -24,6 +25,7 @@ import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
|
|
@ -93,6 +95,17 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<R
|
||||||
return AnnotationUtils.findAnnotation(beanType, Controller.class) != null;
|
return AnnotationUtils.findAnnotation(beanType, Controller.class) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void handlerMethodsInitialized(Map<RequestMappingInfo, HandlerMethod> handlerMethods) {
|
||||||
|
List<RequestMappingInfo> mappings = new ArrayList<RequestMappingInfo>(handlerMethods.keySet());
|
||||||
|
while (mappings.size() > 1) {
|
||||||
|
RequestMappingInfo mapping = mappings.remove(0);
|
||||||
|
for (RequestMappingInfo otherMapping : mappings) {
|
||||||
|
// further validate mapping conditions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides a {@link RequestMappingInfo} for the given method.
|
* Provides a {@link RequestMappingInfo} for the given method.
|
||||||
* <p>Only {@link RequestMapping @RequestMapping}-annotated methods are considered.
|
* <p>Only {@link RequestMapping @RequestMapping}-annotated methods are considered.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue