Add method to allow further validation of request mapping infos at startup + other minor javadoc updates.
This commit is contained in:
parent
2afeb08e3c
commit
b46598965e
|
|
@ -59,7 +59,6 @@ import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
|
|||
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
|
||||
import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite;
|
||||
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.mvc.Controller;
|
||||
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||
|
|
@ -88,7 +87,7 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv
|
|||
* </ul>
|
||||
*
|
||||
* <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:
|
||||
* <ul>
|
||||
|
|
@ -108,7 +107,6 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv
|
|||
* <ul>
|
||||
* <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 MappedInterceptors} containing a list Spring MVC lifecycle interceptors.
|
||||
* </ul>
|
||||
*
|
||||
* @see EnableWebMvc
|
||||
|
|
@ -128,7 +126,7 @@ class WebMvcConfiguration implements ApplicationContextAware, ServletContextAwar
|
|||
|
||||
@Autowired(required = false)
|
||||
public void setConfigurers(List<WebMvcConfigurer> configurers) {
|
||||
this.configurers.addConfigurers(configurers);
|
||||
this.configurers.addWebMvcConfigurers(configurers);
|
||||
}
|
||||
|
||||
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.
|
||||
*/
|
||||
void addFormatters(FormatterRegistry formatterRegistry);
|
||||
void addFormatters(FormatterRegistry registry);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @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.
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
void configureResourceHandling(ResourceConfigurer resourceConfigurer);
|
||||
void configureResourceHandling(ResourceConfigurer configurer);
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* 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}
|
||||
* <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}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void configureInterceptors(InterceptorConfigurer interceptorConfigurer) {
|
||||
public void configureInterceptors(InterceptorConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void configureViewControllers(ViewControllerConfigurer viewControllerConfigurer) {
|
||||
public void configureViewControllers(ViewControllerConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void configureResourceHandling(ResourceConfigurer resourceConfigurer) {
|
||||
public void configureResourceHandling(ResourceConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <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 {
|
||||
|
||||
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) {
|
||||
this.configurers.addAll(configurers);
|
||||
this.delegates.addAll(configurers);
|
||||
}
|
||||
}
|
||||
|
||||
public void addFormatters(FormatterRegistry formatterRegistry) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.addFormatters(formatterRegistry);
|
||||
public void addFormatters(FormatterRegistry registry) {
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
delegate.addFormatters(registry);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.configureMessageConverters(converters);
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
delegate.configureMessageConverters(converters);
|
||||
}
|
||||
}
|
||||
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.addArgumentResolvers(argumentResolvers);
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
delegate.addArgumentResolvers(argumentResolvers);
|
||||
}
|
||||
}
|
||||
|
||||
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.addReturnValueHandlers(returnValueHandlers);
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
delegate.addReturnValueHandlers(returnValueHandlers);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.configureHandlerExceptionResolvers(exceptionResolvers);
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
delegate.configureHandlerExceptionResolvers(exceptionResolvers);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureInterceptors(InterceptorConfigurer interceptorRegistry) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.configureInterceptors(interceptorRegistry);
|
||||
public void configureInterceptors(InterceptorConfigurer configurer) {
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
delegate.configureInterceptors(configurer);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureViewControllers(ViewControllerConfigurer viewControllerConfigurer) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.configureViewControllers(viewControllerConfigurer);
|
||||
public void configureViewControllers(ViewControllerConfigurer configurer) {
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
delegate.configureViewControllers(configurer);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureResourceHandling(ResourceConfigurer resourceConfigurer) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.configureResourceHandling(resourceConfigurer);
|
||||
public void configureResourceHandling(ResourceConfigurer configurer) {
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
delegate.configureResourceHandling(configurer);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer handlerConfigurer) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.configureDefaultServletHandling(handlerConfigurer);
|
||||
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
delegate.configureDefaultServletHandling(configurer);
|
||||
}
|
||||
}
|
||||
|
||||
public Validator getValidator() {
|
||||
Map<WebMvcConfigurer, Validator> validators = new HashMap<WebMvcConfigurer, Validator>();
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
Validator validator = configurer.getValidator();
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
Validator validator = delegate.getValidator();
|
||||
if (validator != null) {
|
||||
validators.put(configurer, validator);
|
||||
validators.put(delegate, validator);
|
||||
}
|
||||
}
|
||||
if (validators.size() == 0) {
|
||||
|
|
|
|||
|
|
@ -127,6 +127,7 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
|||
detectHandlerMethods(beanName);
|
||||
}
|
||||
}
|
||||
handlerMethodsInitialized(getHandlerMethods());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -136,6 +137,13 @@ public abstract class AbstractHandlerMethodMapping<T> extends AbstractHandlerMap
|
|||
*/
|
||||
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.
|
||||
* @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
|
||||
* {@link InitBinder} methods. Custom argument resolvers are given a chance to resolve argument values
|
||||
* ahead of the standard argument resolvers registered by default.
|
||||
* {@link InitBinder} methods.
|
||||
* <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}
|
||||
* 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.
|
||||
* Custom return value handlers are given a chance to handle a return value before the standard
|
||||
* return value handlers registered by default.
|
||||
* <p>Generally custom return value handlers are invoked first. However this excludes default return value
|
||||
* 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
|
||||
*/
|
||||
public void setCustomReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.web.servlet.mvc.method.annotation;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashSet;
|
||||
|
|
@ -24,6 +25,7 @@ import java.util.Iterator;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.springframework.core.annotation.AnnotationUtils;
|
||||
|
|
@ -93,6 +95,17 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<R
|
|||
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.
|
||||
* <p>Only {@link RequestMapping @RequestMapping}-annotated methods are considered.
|
||||
|
|
|
|||
Loading…
Reference in New Issue