SPR-8352 Init and apply MappedInterceptors from AbstractHandlerMapping
This commit is contained in:
parent
60aa598c03
commit
0bf92782ea
|
|
@ -18,6 +18,7 @@ Changes in version 3.1 M2 (2011-??-??)
|
||||||
* support for URI template variables in view names with the "redirect:" prefix
|
* support for URI template variables in view names with the "redirect:" prefix
|
||||||
* a flag for extracting the value from single-key models in MappingJacksonJsonView
|
* a flag for extracting the value from single-key models in MappingJacksonJsonView
|
||||||
* allow bean references in mvc:interceptor namespace elements
|
* allow bean references in mvc:interceptor namespace elements
|
||||||
|
* consolidated the initialization and use of MappedInterceptors in AbstractHandlerMapping
|
||||||
|
|
||||||
Changes in version 3.1 M1 (2011-02-11)
|
Changes in version 3.1 M1 (2011-02-11)
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -118,8 +118,8 @@ public class InterceptorConfigurer {
|
||||||
/**
|
/**
|
||||||
* Returns all registered interceptors.
|
* Returns all registered interceptors.
|
||||||
*/
|
*/
|
||||||
protected MappedInterceptor[] getInterceptors() {
|
protected List<MappedInterceptor> getInterceptors() {
|
||||||
return mappedInterceptors.toArray(new MappedInterceptor[mappedInterceptors.size()]);
|
return mappedInterceptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -124,8 +124,15 @@ class WebMvcConfiguration implements ApplicationContextAware, ServletContextAwar
|
||||||
|
|
||||||
private ApplicationContext applicationContext;
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
private List<MappedInterceptor> mappedInterceptors;
|
||||||
|
|
||||||
|
private List<HttpMessageConverter<?>> messageConverters;
|
||||||
|
|
||||||
@Autowired(required = false)
|
@Autowired(required = false)
|
||||||
public void setConfigurers(List<WebMvcConfigurer> configurers) {
|
public void setConfigurers(List<WebMvcConfigurer> configurers) {
|
||||||
|
if (configurers == null || configurers.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.configurers.addWebMvcConfigurers(configurers);
|
this.configurers.addWebMvcConfigurers(configurers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,17 +147,19 @@ class WebMvcConfiguration implements ApplicationContextAware, ServletContextAwar
|
||||||
@Bean
|
@Bean
|
||||||
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
|
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
|
||||||
RequestMappingHandlerMapping mapping = new RequestMappingHandlerMapping();
|
RequestMappingHandlerMapping mapping = new RequestMappingHandlerMapping();
|
||||||
mapping.setMappedInterceptors(getMappedInterceptors());
|
mapping.setInterceptors(getMappedInterceptors());
|
||||||
mapping.setOrder(0);
|
mapping.setOrder(0);
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MappedInterceptor[] getMappedInterceptors() {
|
private Object[] getMappedInterceptors() {
|
||||||
// TODO : prepare and store in instance var ?
|
if (mappedInterceptors == null) {
|
||||||
InterceptorConfigurer configurer = new InterceptorConfigurer();
|
InterceptorConfigurer configurer = new InterceptorConfigurer();
|
||||||
configurers.configureInterceptors(configurer);
|
configurers.configureInterceptors(configurer);
|
||||||
configurer.addInterceptor(new ConversionServiceExposingInterceptor(conversionService()));
|
configurer.addInterceptor(new ConversionServiceExposingInterceptor(conversionService()));
|
||||||
return configurer.getInterceptors();
|
mappedInterceptors = configurer.getInterceptors();
|
||||||
|
}
|
||||||
|
return mappedInterceptors.toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
|
@ -160,7 +169,7 @@ class WebMvcConfiguration implements ApplicationContextAware, ServletContextAwar
|
||||||
configurers.configureViewControllers(configurer);
|
configurers.configureViewControllers(configurer);
|
||||||
|
|
||||||
SimpleUrlHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
SimpleUrlHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
||||||
handlerMapping.setMappedInterceptors(getMappedInterceptors());
|
handlerMapping.setInterceptors(getMappedInterceptors());
|
||||||
return handlerMapping;
|
return handlerMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -168,7 +177,7 @@ class WebMvcConfiguration implements ApplicationContextAware, ServletContextAwar
|
||||||
public BeanNameUrlHandlerMapping beanNameHandlerMapping() {
|
public BeanNameUrlHandlerMapping beanNameHandlerMapping() {
|
||||||
BeanNameUrlHandlerMapping mapping = new BeanNameUrlHandlerMapping();
|
BeanNameUrlHandlerMapping mapping = new BeanNameUrlHandlerMapping();
|
||||||
mapping.setOrder(2);
|
mapping.setOrder(2);
|
||||||
mapping.setMappedInterceptors(getMappedInterceptors());
|
mapping.setInterceptors(getMappedInterceptors());
|
||||||
return mapping;
|
return mapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -190,6 +199,7 @@ class WebMvcConfiguration implements ApplicationContextAware, ServletContextAwar
|
||||||
@Bean
|
@Bean
|
||||||
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
|
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
|
||||||
RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
|
RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
|
||||||
|
adapter.setMessageConverters(getMessageConverters());
|
||||||
|
|
||||||
ConfigurableWebBindingInitializer bindingInitializer = new ConfigurableWebBindingInitializer();
|
ConfigurableWebBindingInitializer bindingInitializer = new ConfigurableWebBindingInitializer();
|
||||||
bindingInitializer.setConversionService(conversionService());
|
bindingInitializer.setConversionService(conversionService());
|
||||||
|
|
@ -204,24 +214,28 @@ class WebMvcConfiguration implements ApplicationContextAware, ServletContextAwar
|
||||||
configurers.addReturnValueHandlers(returnValueHandlers);
|
configurers.addReturnValueHandlers(returnValueHandlers);
|
||||||
adapter.setCustomReturnValueHandlers(returnValueHandlers);
|
adapter.setCustomReturnValueHandlers(returnValueHandlers);
|
||||||
|
|
||||||
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
|
|
||||||
configurers.configureMessageConverters(converters);
|
|
||||||
if (converters.size() == 0) {
|
|
||||||
addDefaultHttpMessageConverters(converters);
|
|
||||||
}
|
|
||||||
adapter.setMessageConverters(converters);
|
|
||||||
|
|
||||||
return adapter;
|
return adapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(name="mvcConversionService")
|
private List<HttpMessageConverter<?>> getMessageConverters() {
|
||||||
|
if (messageConverters == null) {
|
||||||
|
messageConverters = new ArrayList<HttpMessageConverter<?>>();
|
||||||
|
configurers.configureMessageConverters(messageConverters);
|
||||||
|
if (messageConverters.isEmpty()) {
|
||||||
|
addDefaultHttpMessageConverters(messageConverters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return messageConverters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name="webMvcConversionService")
|
||||||
public FormattingConversionService conversionService() {
|
public FormattingConversionService conversionService() {
|
||||||
FormattingConversionService conversionService = new DefaultFormattingConversionService();
|
FormattingConversionService conversionService = new DefaultFormattingConversionService();
|
||||||
configurers.addFormatters(conversionService);
|
configurers.addFormatters(conversionService);
|
||||||
return conversionService;
|
return conversionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean(name="mvcValidator")
|
@Bean(name="webMvcValidator")
|
||||||
public Validator validator() {
|
public Validator validator() {
|
||||||
Validator validator = configurers.getValidator();
|
Validator validator = configurers.getValidator();
|
||||||
if (validator != null) {
|
if (validator != null) {
|
||||||
|
|
@ -240,37 +254,30 @@ class WebMvcConfiguration implements ApplicationContextAware, ServletContextAwar
|
||||||
return (Validator) BeanUtils.instantiate(clazz);
|
return (Validator) BeanUtils.instantiate(clazz);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return new Validator() {
|
return NOOP_VALIDATOR;
|
||||||
public void validate(Object target, Errors errors) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean supports(Class<?> clazz) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> converters) {
|
private void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
|
||||||
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
|
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
|
||||||
stringConverter.setWriteAcceptCharset(false);
|
stringConverter.setWriteAcceptCharset(false);
|
||||||
|
|
||||||
converters.add(new ByteArrayHttpMessageConverter());
|
messageConverters.add(new ByteArrayHttpMessageConverter());
|
||||||
converters.add(stringConverter);
|
messageConverters.add(stringConverter);
|
||||||
converters.add(new ResourceHttpMessageConverter());
|
messageConverters.add(new ResourceHttpMessageConverter());
|
||||||
converters.add(new SourceHttpMessageConverter<Source>());
|
messageConverters.add(new SourceHttpMessageConverter<Source>());
|
||||||
converters.add(new XmlAwareFormHttpMessageConverter());
|
messageConverters.add(new XmlAwareFormHttpMessageConverter());
|
||||||
|
|
||||||
ClassLoader classLoader = getClass().getClassLoader();
|
ClassLoader classLoader = getClass().getClassLoader();
|
||||||
if (ClassUtils.isPresent("javax.xml.bind.Binder", classLoader)) {
|
if (ClassUtils.isPresent("javax.xml.bind.Binder", classLoader)) {
|
||||||
converters.add(new Jaxb2RootElementHttpMessageConverter());
|
messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
|
||||||
}
|
}
|
||||||
if (ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper", classLoader)) {
|
if (ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper", classLoader)) {
|
||||||
converters.add(new MappingJacksonHttpMessageConverter());
|
messageConverters.add(new MappingJacksonHttpMessageConverter());
|
||||||
}
|
}
|
||||||
if (ClassUtils.isPresent("com.sun.syndication.feed.WireFeed", classLoader)) {
|
if (ClassUtils.isPresent("com.sun.syndication.feed.WireFeed", classLoader)) {
|
||||||
converters.add(new AtomFeedHttpMessageConverter());
|
messageConverters.add(new AtomFeedHttpMessageConverter());
|
||||||
converters.add(new RssChannelHttpMessageConverter());
|
messageConverters.add(new RssChannelHttpMessageConverter());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -303,16 +310,19 @@ class WebMvcConfiguration implements ApplicationContextAware, ServletContextAwar
|
||||||
|
|
||||||
private HandlerExceptionResolver createExceptionHandlerExceptionResolver() throws Exception {
|
private HandlerExceptionResolver createExceptionHandlerExceptionResolver() throws Exception {
|
||||||
ExceptionHandlerExceptionResolver resolver = new ExceptionHandlerExceptionResolver();
|
ExceptionHandlerExceptionResolver resolver = new ExceptionHandlerExceptionResolver();
|
||||||
|
resolver.setMessageConverters(getMessageConverters());
|
||||||
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
|
|
||||||
configurers.configureMessageConverters(converters);
|
|
||||||
if (converters.size() == 0) {
|
|
||||||
addDefaultHttpMessageConverters(converters);
|
|
||||||
}
|
|
||||||
resolver.setMessageConverters(converters);
|
|
||||||
|
|
||||||
resolver.afterPropertiesSet();
|
resolver.afterPropertiesSet();
|
||||||
return resolver;
|
return resolver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static final Validator NOOP_VALIDATOR = new Validator() {
|
||||||
|
|
||||||
|
public boolean supports(Class<?> clazz) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void validate(Object target, Errors errors) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,28 +19,39 @@ package org.springframework.web.servlet.handler;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||||
import org.springframework.core.Ordered;
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.PathMatcher;
|
||||||
import org.springframework.web.context.request.WebRequestInterceptor;
|
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||||
import org.springframework.web.context.support.WebApplicationObjectSupport;
|
import org.springframework.web.context.support.WebApplicationObjectSupport;
|
||||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
import org.springframework.web.servlet.HandlerExecutionChain;
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for {@link org.springframework.web.servlet.HandlerMapping}
|
* Abstract base class for {@link org.springframework.web.servlet.HandlerMapping}
|
||||||
* implementations. Supports ordering, a default handler, and handler interceptors.
|
* implementations. Supports ordering, a default handler, handler interceptors,
|
||||||
|
* including handler interceptors mapped by path patterns.
|
||||||
*
|
*
|
||||||
* <p>Note: This base class does <i>not</i> support exposure of the
|
* <p>Note: This base class does <i>not</i> support exposure of the
|
||||||
* {@link #PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE}. Support for this attribute
|
* {@link #PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE}. Support for this attribute
|
||||||
* is up to concrete subclasses, typically based on request URL mappings.
|
* is up to concrete subclasses, typically based on request URL mappings.
|
||||||
*
|
*
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
* @since 07.04.2003
|
* @since 07.04.2003
|
||||||
* @see #getHandlerInternal
|
* @see #getHandlerInternal
|
||||||
* @see #setDefaultHandler
|
* @see #setDefaultHandler
|
||||||
|
* @see #setAlwaysUseFullPath
|
||||||
|
* @see #setUrlDecode
|
||||||
|
* @see org.springframework.util.AntPathMatcher
|
||||||
* @see #setInterceptors
|
* @see #setInterceptors
|
||||||
* @see org.springframework.web.servlet.HandlerInterceptor
|
* @see org.springframework.web.servlet.HandlerInterceptor
|
||||||
*/
|
*/
|
||||||
|
|
@ -51,10 +62,15 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
|
||||||
|
|
||||||
private Object defaultHandler;
|
private Object defaultHandler;
|
||||||
|
|
||||||
|
private UrlPathHelper urlPathHelper = new UrlPathHelper();
|
||||||
|
|
||||||
|
private PathMatcher pathMatcher = new AntPathMatcher();
|
||||||
|
|
||||||
private final List<Object> interceptors = new ArrayList<Object>();
|
private final List<Object> interceptors = new ArrayList<Object>();
|
||||||
|
|
||||||
private HandlerInterceptor[] adaptedInterceptors;
|
private final List<HandlerInterceptor> adaptedInterceptors = new ArrayList<HandlerInterceptor>();
|
||||||
|
|
||||||
|
private final List<MappedInterceptor> mappedInterceptors = new ArrayList<MappedInterceptor>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specify the order value for this HandlerMapping bean.
|
* Specify the order value for this HandlerMapping bean.
|
||||||
|
|
@ -86,9 +102,69 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
|
||||||
return this.defaultHandler;
|
return this.defaultHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if URL lookup should always use the full path within the current servlet
|
||||||
|
* context. Else, the path within the current servlet mapping is used if applicable
|
||||||
|
* (that is, in the case of a ".../*" servlet mapping in web.xml).
|
||||||
|
* <p>Default is "false".
|
||||||
|
* @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath
|
||||||
|
*/
|
||||||
|
public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
|
||||||
|
this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if context path and request URI should be URL-decoded. Both are returned
|
||||||
|
* <i>undecoded</i> by the Servlet API, in contrast to the servlet path.
|
||||||
|
* <p>Uses either the request encoding or the default encoding according
|
||||||
|
* to the Servlet spec (ISO-8859-1).
|
||||||
|
* @see org.springframework.web.util.UrlPathHelper#setUrlDecode
|
||||||
|
*/
|
||||||
|
public void setUrlDecode(boolean urlDecode) {
|
||||||
|
this.urlPathHelper.setUrlDecode(urlDecode);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the UrlPathHelper to use for resolution of lookup paths.
|
||||||
|
* <p>Use this to override the default UrlPathHelper with a custom subclass,
|
||||||
|
* or to share common UrlPathHelper settings across multiple HandlerMappings
|
||||||
|
* and MethodNameResolvers.
|
||||||
|
*/
|
||||||
|
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
|
||||||
|
Assert.notNull(urlPathHelper, "UrlPathHelper must not be null");
|
||||||
|
this.urlPathHelper = urlPathHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the UrlPathHelper implementation to use for resolution of lookup paths.
|
||||||
|
*/
|
||||||
|
public UrlPathHelper getUrlPathHelper() {
|
||||||
|
return urlPathHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the PathMatcher implementation to use for matching URL paths
|
||||||
|
* against registered URL patterns. Default is AntPathMatcher.
|
||||||
|
* @see org.springframework.util.AntPathMatcher
|
||||||
|
*/
|
||||||
|
public void setPathMatcher(PathMatcher pathMatcher) {
|
||||||
|
Assert.notNull(pathMatcher, "PathMatcher must not be null");
|
||||||
|
this.pathMatcher = pathMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the PathMatcher implementation to use for matching URL paths
|
||||||
|
* against registered URL patterns.
|
||||||
|
*/
|
||||||
|
public PathMatcher getPathMatcher() {
|
||||||
|
return this.pathMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the interceptors to apply for all handlers mapped by this handler mapping.
|
* Set the interceptors to apply for all handlers mapped by this handler mapping.
|
||||||
* <p>Supported interceptor types are HandlerInterceptor and WebRequestInterceptor.
|
* <p>Supported interceptor types are HandlerInterceptor, WebRequestInterceptor, and MappedInterceptor.
|
||||||
|
* Mapped interceptors apply only to request URLs that match its path patterns.
|
||||||
|
* Mapped interceptor beans are also detected by type during initialization.
|
||||||
* @param interceptors array of handler interceptors, or <code>null</code> if none
|
* @param interceptors array of handler interceptors, or <code>null</code> if none
|
||||||
* @see #adaptInterceptor
|
* @see #adaptInterceptor
|
||||||
* @see org.springframework.web.servlet.HandlerInterceptor
|
* @see org.springframework.web.servlet.HandlerInterceptor
|
||||||
|
|
@ -107,6 +183,7 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
|
||||||
@Override
|
@Override
|
||||||
protected void initApplicationContext() throws BeansException {
|
protected void initApplicationContext() throws BeansException {
|
||||||
extendInterceptors(this.interceptors);
|
extendInterceptors(this.interceptors);
|
||||||
|
detectMappedInterceptors(this.mappedInterceptors);
|
||||||
initInterceptors();
|
initInterceptors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,19 +201,37 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize the specified interceptors, adapting them where necessary.
|
* Detects beans of type {@link MappedInterceptor} and adds them to the list of mapped interceptors.
|
||||||
|
* This is done in addition to any {@link MappedInterceptor}s that may have been provided via
|
||||||
|
* {@link #setInterceptors(Object[])}. Subclasses can override this method to change that.
|
||||||
|
*
|
||||||
|
* @param mappedInterceptors an empty list to add MappedInterceptor types to
|
||||||
|
*/
|
||||||
|
protected void detectMappedInterceptors(List<MappedInterceptor> mappedInterceptors) {
|
||||||
|
mappedInterceptors.addAll(
|
||||||
|
BeanFactoryUtils.beansOfTypeIncludingAncestors(
|
||||||
|
getApplicationContext(),MappedInterceptor.class, true, false).values());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the specified interceptors, checking for {@link MappedInterceptor}s and adapting
|
||||||
|
* HandlerInterceptors where necessary.
|
||||||
* @see #setInterceptors
|
* @see #setInterceptors
|
||||||
* @see #adaptInterceptor
|
* @see #adaptInterceptor
|
||||||
*/
|
*/
|
||||||
protected void initInterceptors() {
|
protected void initInterceptors() {
|
||||||
if (!this.interceptors.isEmpty()) {
|
if (!this.interceptors.isEmpty()) {
|
||||||
this.adaptedInterceptors = new HandlerInterceptor[this.interceptors.size()];
|
|
||||||
for (int i = 0; i < this.interceptors.size(); i++) {
|
for (int i = 0; i < this.interceptors.size(); i++) {
|
||||||
Object interceptor = this.interceptors.get(i);
|
Object interceptor = this.interceptors.get(i);
|
||||||
if (interceptor == null) {
|
if (interceptor == null) {
|
||||||
throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null");
|
throw new IllegalArgumentException("Entry number " + i + " in interceptors array is null");
|
||||||
}
|
}
|
||||||
this.adaptedInterceptors[i] = adaptInterceptor(interceptor);
|
if (interceptor instanceof MappedInterceptor) {
|
||||||
|
mappedInterceptors.add((MappedInterceptor) interceptor);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
adaptedInterceptors.add(adaptInterceptor(interceptor));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -169,9 +264,18 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
|
||||||
* @return the array of HandlerInterceptors, or <code>null</code> if none
|
* @return the array of HandlerInterceptors, or <code>null</code> if none
|
||||||
*/
|
*/
|
||||||
protected final HandlerInterceptor[] getAdaptedInterceptors() {
|
protected final HandlerInterceptor[] getAdaptedInterceptors() {
|
||||||
return this.adaptedInterceptors;
|
int count = adaptedInterceptors.size();
|
||||||
|
return (count > 0) ? adaptedInterceptors.toArray(new HandlerInterceptor[count]) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all configured {@link MappedInterceptor}s as an array.
|
||||||
|
* @return the array of {@link MappedInterceptor}s, or <code>null</code> if none
|
||||||
|
*/
|
||||||
|
protected final MappedInterceptor[] getMappedInterceptors() {
|
||||||
|
int count = mappedInterceptors.size();
|
||||||
|
return (count > 0) ? mappedInterceptors.toArray(new MappedInterceptor[count]) : null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up a handler for the given request, falling back to the default
|
* Look up a handler for the given request, falling back to the default
|
||||||
|
|
@ -212,7 +316,8 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
|
||||||
/**
|
/**
|
||||||
* Build a HandlerExecutionChain for the given handler, including applicable interceptors.
|
* Build a HandlerExecutionChain for the given handler, including applicable interceptors.
|
||||||
* <p>The default implementation simply builds a standard HandlerExecutionChain with
|
* <p>The default implementation simply builds a standard HandlerExecutionChain with
|
||||||
* the given handler and this handler mapping's common interceptors. Subclasses may
|
* the given handler, the handler mapping's common interceptors, and any {@link MappedInterceptor}s
|
||||||
|
* matching to the current request URL. Subclasses may
|
||||||
* override this in order to extend/rearrange the list of interceptors.
|
* override this in order to extend/rearrange the list of interceptors.
|
||||||
* <p><b>NOTE:</b> The passed-in handler object may be a raw handler or a pre-built
|
* <p><b>NOTE:</b> The passed-in handler object may be a raw handler or a pre-built
|
||||||
* HandlerExecutionChain. This method should handle those two cases explicitly,
|
* HandlerExecutionChain. This method should handle those two cases explicitly,
|
||||||
|
|
@ -225,14 +330,20 @@ public abstract class AbstractHandlerMapping extends WebApplicationObjectSupport
|
||||||
* @see #getAdaptedInterceptors()
|
* @see #getAdaptedInterceptors()
|
||||||
*/
|
*/
|
||||||
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
|
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
|
||||||
if (handler instanceof HandlerExecutionChain) {
|
HandlerExecutionChain chain =
|
||||||
HandlerExecutionChain chain = (HandlerExecutionChain) handler;
|
(handler instanceof HandlerExecutionChain) ?
|
||||||
chain.addInterceptors(getAdaptedInterceptors());
|
(HandlerExecutionChain) handler : new HandlerExecutionChain(handler);
|
||||||
return chain;
|
|
||||||
}
|
chain.addInterceptors(getAdaptedInterceptors());
|
||||||
else {
|
|
||||||
return new HandlerExecutionChain(handler, getAdaptedInterceptors());
|
String lookupPath = urlPathHelper.getLookupPathForRequest(request);
|
||||||
|
for (MappedInterceptor mappedInterceptor : mappedInterceptors) {
|
||||||
|
if (mappedInterceptor.matches(lookupPath, pathMatcher)) {
|
||||||
|
chain.addInterceptor(mappedInterceptor.getInterceptor());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return chain;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,14 +27,10 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.util.AntPathMatcher;
|
|
||||||
import org.springframework.util.Assert;
|
import org.springframework.util.Assert;
|
||||||
import org.springframework.util.CollectionUtils;
|
import org.springframework.util.CollectionUtils;
|
||||||
import org.springframework.util.PathMatcher;
|
|
||||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
import org.springframework.web.servlet.HandlerExecutionChain;
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
import org.springframework.web.util.UrlPathHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abstract base class for URL-mapped {@link org.springframework.web.servlet.HandlerMapping}
|
* Abstract base class for URL-mapped {@link org.springframework.web.servlet.HandlerMapping}
|
||||||
|
|
@ -54,76 +50,15 @@ import org.springframework.web.util.UrlPathHelper;
|
||||||
* @author Juergen Hoeller
|
* @author Juergen Hoeller
|
||||||
* @author Arjen Poutsma
|
* @author Arjen Poutsma
|
||||||
* @since 16.04.2003
|
* @since 16.04.2003
|
||||||
* @see #setAlwaysUseFullPath
|
|
||||||
* @see #setUrlDecode
|
|
||||||
* @see org.springframework.util.AntPathMatcher
|
|
||||||
*/
|
*/
|
||||||
public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
|
public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
|
||||||
|
|
||||||
private UrlPathHelper urlPathHelper = new UrlPathHelper();
|
|
||||||
|
|
||||||
private PathMatcher pathMatcher = new AntPathMatcher();
|
|
||||||
|
|
||||||
private Object rootHandler;
|
private Object rootHandler;
|
||||||
|
|
||||||
private boolean lazyInitHandlers = false;
|
private boolean lazyInitHandlers = false;
|
||||||
|
|
||||||
private final Map<String, Object> handlerMap = new LinkedHashMap<String, Object>();
|
private final Map<String, Object> handlerMap = new LinkedHashMap<String, Object>();
|
||||||
|
|
||||||
private MappedInterceptors mappedInterceptors;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set if URL lookup should always use the full path within the current servlet
|
|
||||||
* context. Else, the path within the current servlet mapping is used if applicable
|
|
||||||
* (that is, in the case of a ".../*" servlet mapping in web.xml).
|
|
||||||
* <p>Default is "false".
|
|
||||||
* @see org.springframework.web.util.UrlPathHelper#setAlwaysUseFullPath
|
|
||||||
*/
|
|
||||||
public void setAlwaysUseFullPath(boolean alwaysUseFullPath) {
|
|
||||||
this.urlPathHelper.setAlwaysUseFullPath(alwaysUseFullPath);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set if context path and request URI should be URL-decoded. Both are returned
|
|
||||||
* <i>undecoded</i> by the Servlet API, in contrast to the servlet path.
|
|
||||||
* <p>Uses either the request encoding or the default encoding according
|
|
||||||
* to the Servlet spec (ISO-8859-1).
|
|
||||||
* @see org.springframework.web.util.UrlPathHelper#setUrlDecode
|
|
||||||
*/
|
|
||||||
public void setUrlDecode(boolean urlDecode) {
|
|
||||||
this.urlPathHelper.setUrlDecode(urlDecode);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the UrlPathHelper to use for resolution of lookup paths.
|
|
||||||
* <p>Use this to override the default UrlPathHelper with a custom subclass,
|
|
||||||
* or to share common UrlPathHelper settings across multiple HandlerMappings
|
|
||||||
* and MethodNameResolvers.
|
|
||||||
* @see org.springframework.web.servlet.mvc.multiaction.AbstractUrlMethodNameResolver#setUrlPathHelper
|
|
||||||
*/
|
|
||||||
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
|
|
||||||
Assert.notNull(urlPathHelper, "UrlPathHelper must not be null");
|
|
||||||
this.urlPathHelper = urlPathHelper;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the PathMatcher implementation to use for matching URL paths
|
|
||||||
* against registered URL patterns. Default is AntPathMatcher.
|
|
||||||
* @see org.springframework.util.AntPathMatcher
|
|
||||||
*/
|
|
||||||
public void setPathMatcher(PathMatcher pathMatcher) {
|
|
||||||
Assert.notNull(pathMatcher, "PathMatcher must not be null");
|
|
||||||
this.pathMatcher = pathMatcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the PathMatcher implementation to use for matching URL paths
|
|
||||||
* against registered URL patterns.
|
|
||||||
*/
|
|
||||||
public PathMatcher getPathMatcher() {
|
|
||||||
return this.pathMatcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the root handler for this handler mapping, that is,
|
* Set the root handler for this handler mapping, that is,
|
||||||
|
|
@ -156,19 +91,6 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
|
||||||
this.lazyInitHandlers = lazyInitHandlers;
|
this.lazyInitHandlers = lazyInitHandlers;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setMappedInterceptors(MappedInterceptor[] mappedInterceptors) {
|
|
||||||
this.mappedInterceptors = new MappedInterceptors(mappedInterceptors);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initInterceptors() {
|
|
||||||
super.initInterceptors();
|
|
||||||
if (mappedInterceptors == null) {
|
|
||||||
this.mappedInterceptors = MappedInterceptors.createFromDeclaredBeans(getApplicationContext());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Look up a handler for the URL path of the given request.
|
* Look up a handler for the URL path of the given request.
|
||||||
* @param request current HTTP request
|
* @param request current HTTP request
|
||||||
|
|
@ -176,7 +98,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
|
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
|
||||||
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
|
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
|
||||||
Object handler = lookupHandler(lookupPath, request);
|
Object handler = lookupHandler(lookupPath, request);
|
||||||
if (handler == null) {
|
if (handler == null) {
|
||||||
// We need to care for the default handler directly, since we need to
|
// We need to care for the default handler directly, since we need to
|
||||||
|
|
@ -287,19 +209,6 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
|
||||||
protected void validateHandler(Object handler, HttpServletRequest request) throws Exception {
|
protected void validateHandler(Object handler, HttpServletRequest request) throws Exception {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
|
|
||||||
HandlerExecutionChain chain = super.getHandlerExecutionChain(handler, request);
|
|
||||||
if (this.mappedInterceptors != null) {
|
|
||||||
String lookupPath = urlPathHelper.getLookupPathForRequest(request);
|
|
||||||
HandlerInterceptor[] handlerInterceptors = mappedInterceptors.getInterceptors(lookupPath, pathMatcher);
|
|
||||||
if (handlerInterceptors.length > 0) {
|
|
||||||
chain.addInterceptors(handlerInterceptors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return chain;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a handler object for the given raw handler, exposing the actual
|
* Build a handler object for the given raw handler, exposing the actual
|
||||||
* handler, the {@link #PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE}, as well as
|
* handler, the {@link #PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE}, as well as
|
||||||
|
|
@ -434,7 +343,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
|
||||||
/**
|
/**
|
||||||
* Special interceptor for exposing the
|
* Special interceptor for exposing the
|
||||||
* {@link AbstractUrlHandlerMapping#PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE} attribute.
|
* {@link AbstractUrlHandlerMapping#PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE} attribute.
|
||||||
* @link AbstractUrlHandlerMapping#exposePathWithinMapping
|
* @see AbstractUrlHandlerMapping#exposePathWithinMapping
|
||||||
*/
|
*/
|
||||||
private class PathExposingHandlerInterceptor extends HandlerInterceptorAdapter {
|
private class PathExposingHandlerInterceptor extends HandlerInterceptorAdapter {
|
||||||
|
|
||||||
|
|
@ -459,7 +368,7 @@ public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping {
|
||||||
/**
|
/**
|
||||||
* Special interceptor for exposing the
|
* Special interceptor for exposing the
|
||||||
* {@link AbstractUrlHandlerMapping#URI_TEMPLATE_VARIABLES_ATTRIBUTE} attribute.
|
* {@link AbstractUrlHandlerMapping#URI_TEMPLATE_VARIABLES_ATTRIBUTE} attribute.
|
||||||
* @link AbstractUrlHandlerMapping#exposePathWithinMapping
|
* @see AbstractUrlHandlerMapping#exposePathWithinMapping
|
||||||
*/
|
*/
|
||||||
private class UriTemplateVariablesHandlerInterceptor extends HandlerInterceptorAdapter {
|
private class UriTemplateVariablesHandlerInterceptor extends HandlerInterceptorAdapter {
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,13 +16,16 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.handler;
|
package org.springframework.web.servlet.handler;
|
||||||
|
|
||||||
|
import org.springframework.util.PathMatcher;
|
||||||
import org.springframework.web.context.request.WebRequestInterceptor;
|
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds information about a HandlerInterceptor mapped to a path into the application.
|
* Holds information about a HandlerInterceptor mapped to a path into the application.
|
||||||
|
* Provides a method to match a request path to the mapped path patterns.
|
||||||
*
|
*
|
||||||
* @author Keith Donald
|
* @author Keith Donald
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.0
|
* @since 3.0
|
||||||
*/
|
*/
|
||||||
public final class MappedInterceptor {
|
public final class MappedInterceptor {
|
||||||
|
|
@ -33,9 +36,9 @@ public final class MappedInterceptor {
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new mapped interceptor.
|
* Create a new MappedInterceptor instance.
|
||||||
* @param pathPatterns the path patterns
|
* @param pathPatterns the path patterns to map with a {@code null} value matching to all paths
|
||||||
* @param interceptor the interceptor
|
* @param interceptor the HandlerInterceptor instance to map to the given patterns
|
||||||
*/
|
*/
|
||||||
public MappedInterceptor(String[] pathPatterns, HandlerInterceptor interceptor) {
|
public MappedInterceptor(String[] pathPatterns, HandlerInterceptor interceptor) {
|
||||||
this.pathPatterns = pathPatterns;
|
this.pathPatterns = pathPatterns;
|
||||||
|
|
@ -43,9 +46,9 @@ public final class MappedInterceptor {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new mapped interceptor.
|
* Create a new MappedInterceptor instance.
|
||||||
* @param pathPatterns the path patterns
|
* @param pathPatterns the path patterns to map with a {@code null} value matching to all paths
|
||||||
* @param interceptor the interceptor
|
* @param interceptor the WebRequestInterceptor instance to map to the given patterns
|
||||||
*/
|
*/
|
||||||
public MappedInterceptor(String[] pathPatterns, WebRequestInterceptor interceptor) {
|
public MappedInterceptor(String[] pathPatterns, WebRequestInterceptor interceptor) {
|
||||||
this.pathPatterns = pathPatterns;
|
this.pathPatterns = pathPatterns;
|
||||||
|
|
@ -67,4 +70,22 @@ public final class MappedInterceptor {
|
||||||
return this.interceptor;
|
return this.interceptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns {@code true} if the interceptor applies to the given request path.
|
||||||
|
* @param lookupPath the current request path
|
||||||
|
* @param pathMatcher a path matcher for path pattern matching
|
||||||
|
*/
|
||||||
|
public boolean matches(String lookupPath, PathMatcher pathMatcher) {
|
||||||
|
if (pathPatterns == null) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (String pathPattern : pathPatterns) {
|
||||||
|
if (pathMatcher.match(pathPattern, lookupPath)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,73 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2002-2011 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.handler;
|
|
||||||
|
|
||||||
import java.util.LinkedHashSet;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
|
||||||
import org.springframework.beans.factory.ListableBeanFactory;
|
|
||||||
import org.springframework.util.PathMatcher;
|
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
|
||||||
|
|
||||||
public final class MappedInterceptors {
|
|
||||||
|
|
||||||
private MappedInterceptor[] mappedInterceptors;
|
|
||||||
|
|
||||||
public MappedInterceptors(MappedInterceptor[] mappedInterceptors) {
|
|
||||||
this.mappedInterceptors = mappedInterceptors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static MappedInterceptors createFromDeclaredBeans(ListableBeanFactory beanFactory) {
|
|
||||||
Map<String, MappedInterceptor> beans = BeanFactoryUtils.beansOfTypeIncludingAncestors(beanFactory,
|
|
||||||
MappedInterceptor.class, true, false);
|
|
||||||
|
|
||||||
if (!beans.isEmpty()) {
|
|
||||||
return new MappedInterceptors(beans.values().toArray(new MappedInterceptor[beans.size()]));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public HandlerInterceptor[] getInterceptors(String lookupPath, PathMatcher pathMatcher) {
|
|
||||||
Set<HandlerInterceptor> interceptors = new LinkedHashSet<HandlerInterceptor>();
|
|
||||||
for (MappedInterceptor interceptor : this.mappedInterceptors) {
|
|
||||||
if (matches(interceptor, lookupPath, pathMatcher)) {
|
|
||||||
interceptors.add(interceptor.getInterceptor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return interceptors.toArray(new HandlerInterceptor[interceptors.size()]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean matches(MappedInterceptor interceptor, String lookupPath, PathMatcher pathMatcher) {
|
|
||||||
String[] pathPatterns = interceptor.getPathPatterns();
|
|
||||||
if (pathPatterns != null) {
|
|
||||||
for (String pattern : pathPatterns) {
|
|
||||||
if (pathMatcher.match(pattern, lookupPath)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -25,14 +25,13 @@ 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.ServletException;
|
import javax.servlet.ServletException;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
import org.springframework.core.annotation.AnnotationUtils;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.util.AntPathMatcher;
|
|
||||||
import org.springframework.util.Assert;
|
|
||||||
import org.springframework.util.PathMatcher;
|
import org.springframework.util.PathMatcher;
|
||||||
import org.springframework.util.StringUtils;
|
import org.springframework.util.StringUtils;
|
||||||
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
import org.springframework.web.HttpMediaTypeNotAcceptableException;
|
||||||
|
|
@ -41,12 +40,8 @@ import org.springframework.web.HttpRequestMethodNotSupportedException;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMethod;
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
import org.springframework.web.method.HandlerMethod;
|
import org.springframework.web.method.HandlerMethod;
|
||||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
|
import org.springframework.web.servlet.handler.AbstractHandlerMethodMapping;
|
||||||
import org.springframework.web.servlet.handler.MappedInterceptor;
|
|
||||||
import org.springframework.web.servlet.handler.MappedInterceptors;
|
|
||||||
import org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory;
|
import org.springframework.web.servlet.mvc.method.condition.RequestConditionFactory;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -59,36 +54,6 @@ import org.springframework.web.servlet.mvc.method.condition.RequestConditionFact
|
||||||
*/
|
*/
|
||||||
public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<RequestMappingInfo> {
|
public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<RequestMappingInfo> {
|
||||||
|
|
||||||
private PathMatcher pathMatcher = new AntPathMatcher();
|
|
||||||
|
|
||||||
private MappedInterceptors mappedInterceptors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the PathMatcher implementation to use for matching URL paths against registered URL patterns. Default is
|
|
||||||
* AntPathMatcher.
|
|
||||||
*
|
|
||||||
* @see org.springframework.util.AntPathMatcher
|
|
||||||
*/
|
|
||||||
public void setPathMatcher(PathMatcher pathMatcher) {
|
|
||||||
Assert.notNull(pathMatcher, "PathMatcher must not be null");
|
|
||||||
this.pathMatcher = pathMatcher;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the {@link MappedInterceptor} instances to use to intercept handler method invocations.
|
|
||||||
*/
|
|
||||||
public void setMappedInterceptors(MappedInterceptor[] mappedInterceptors) {
|
|
||||||
this.mappedInterceptors = new MappedInterceptors(mappedInterceptors);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void initInterceptors() {
|
|
||||||
super.initInterceptors();
|
|
||||||
if (this.mappedInterceptors == null) {
|
|
||||||
this.mappedInterceptors = MappedInterceptors.createFromDeclaredBeans(getApplicationContext());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc} The handler determination in this method is made based on the presence of a type-level {@link
|
* {@inheritDoc} The handler determination in this method is made based on the presence of a type-level {@link
|
||||||
* Controller} annotation.
|
* Controller} annotation.
|
||||||
|
|
@ -127,7 +92,7 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<R
|
||||||
RequestMapping typeAnnot = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class);
|
RequestMapping typeAnnot = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class);
|
||||||
if (typeAnnot != null) {
|
if (typeAnnot != null) {
|
||||||
RequestMappingInfo typeMapping = createFromRequestMapping(typeAnnot);
|
RequestMappingInfo typeMapping = createFromRequestMapping(typeAnnot);
|
||||||
return typeMapping.combine(methodMapping, pathMatcher);
|
return typeMapping.combine(methodMapping, getPathMatcher());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return methodMapping;
|
return methodMapping;
|
||||||
|
|
@ -161,7 +126,7 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<R
|
||||||
protected RequestMappingInfo getMatchingMapping(RequestMappingInfo mapping,
|
protected RequestMappingInfo getMatchingMapping(RequestMappingInfo mapping,
|
||||||
String lookupPath,
|
String lookupPath,
|
||||||
HttpServletRequest request) {
|
HttpServletRequest request) {
|
||||||
return mapping.getMatchingRequestMapping(lookupPath, request, pathMatcher);
|
return mapping.getMatchingRequestMapping(lookupPath, request, getPathMatcher());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -172,12 +137,18 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<R
|
||||||
return new RequestMappingInfoComparator(lookupPath, request);
|
return new RequestMappingInfoComparator(lookupPath, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Exposes URI template variables and producible media types as request attributes.
|
||||||
|
*
|
||||||
|
* @see HandlerMapping#URI_TEMPLATE_VARIABLES_ATTRIBUTE
|
||||||
|
* @see HandlerMapping#PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void handleMatch(RequestMappingInfo info, String lookupPath, HttpServletRequest request) {
|
protected void handleMatch(RequestMappingInfo info, String lookupPath, HttpServletRequest request) {
|
||||||
super.handleMatch(info, lookupPath, request);
|
super.handleMatch(info, lookupPath, request);
|
||||||
|
|
||||||
String pattern = info.getPatterns().iterator().next();
|
String pattern = info.getPatterns().iterator().next();
|
||||||
Map<String, String> uriTemplateVariables = pathMatcher.extractUriTemplateVariables(pattern, lookupPath);
|
Map<String, String> uriTemplateVariables = getPathMatcher().extractUriTemplateVariables(pattern, lookupPath);
|
||||||
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVariables);
|
request.setAttribute(HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE, uriTemplateVariables);
|
||||||
|
|
||||||
if (!info.getProduces().isEmpty()) {
|
if (!info.getProduces().isEmpty()) {
|
||||||
|
|
@ -200,7 +171,7 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<R
|
||||||
Set<MediaType> producibleMediaTypes = new HashSet<MediaType>();
|
Set<MediaType> producibleMediaTypes = new HashSet<MediaType>();
|
||||||
for (RequestMappingInfo info : requestMappingInfos) {
|
for (RequestMappingInfo info : requestMappingInfos) {
|
||||||
for (String pattern : info.getPatterns()) {
|
for (String pattern : info.getPatterns()) {
|
||||||
if (pathMatcher.match(pattern, lookupPath)) {
|
if (getPathMatcher().match(pattern, lookupPath)) {
|
||||||
if (!info.getMethods().match(request)) {
|
if (!info.getMethods().match(request)) {
|
||||||
for (RequestMethod method : info.getMethods().getMethods()) {
|
for (RequestMethod method : info.getMethods().getMethods()) {
|
||||||
allowedMethods.add(method.name());
|
allowedMethods.add(method.name());
|
||||||
|
|
@ -233,22 +204,6 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<R
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds mapped interceptors to the handler execution chain.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
|
|
||||||
HandlerExecutionChain chain = super.getHandlerExecutionChain(handler, request);
|
|
||||||
if (this.mappedInterceptors != null) {
|
|
||||||
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
|
|
||||||
HandlerInterceptor[] handlerInterceptors = mappedInterceptors.getInterceptors(lookupPath, pathMatcher);
|
|
||||||
if (handlerInterceptors.length > 0) {
|
|
||||||
chain.addInterceptors(handlerInterceptors);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return chain;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A comparator for {@link RequestMappingInfo}s. Effective comparison can only be done in the context of a specific
|
* A comparator for {@link RequestMappingInfo}s. Effective comparison can only be done in the context of a specific
|
||||||
* request. For example not all {@link RequestMappingInfo} patterns may apply to the current request. Therefore an
|
* request. For example not all {@link RequestMappingInfo} patterns may apply to the current request. Therefore an
|
||||||
|
|
@ -267,7 +222,7 @@ public class RequestMappingHandlerMapping extends AbstractHandlerMethodMapping<R
|
||||||
private List<MediaType> requestAcceptHeader;
|
private List<MediaType> requestAcceptHeader;
|
||||||
|
|
||||||
public RequestMappingInfoComparator(String lookupPath, HttpServletRequest request) {
|
public RequestMappingInfoComparator(String lookupPath, HttpServletRequest request) {
|
||||||
this.patternComparator = pathMatcher.getPatternComparator(lookupPath);
|
this.patternComparator = getPathMatcher().getPatternComparator(lookupPath);
|
||||||
String acceptHeader = request.getHeader("Accept");
|
String acceptHeader = request.getHeader("Accept");
|
||||||
this.requestAcceptHeader = MediaType.parseMediaTypes(acceptHeader);
|
this.requestAcceptHeader = MediaType.parseMediaTypes(acceptHeader);
|
||||||
MediaType.sortByQualityValue(this.requestAcceptHeader);
|
MediaType.sortByQualityValue(this.requestAcceptHeader);
|
||||||
|
|
|
||||||
|
|
@ -16,20 +16,24 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.config.annotation;
|
package org.springframework.web.servlet.config.annotation;
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
import org.springframework.mock.web.MockHttpServletResponse;
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
import org.springframework.ui.ModelMap;
|
import org.springframework.ui.ModelMap;
|
||||||
import org.springframework.util.AntPathMatcher;
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
import org.springframework.util.PathMatcher;
|
||||||
import org.springframework.web.context.request.WebRequest;
|
import org.springframework.web.context.request.WebRequest;
|
||||||
import org.springframework.web.context.request.WebRequestInterceptor;
|
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||||
import org.springframework.web.servlet.HandlerInterceptor;
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
import org.springframework.web.servlet.handler.MappedInterceptors;
|
import org.springframework.web.servlet.handler.MappedInterceptor;
|
||||||
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
|
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
|
||||||
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
||||||
import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
|
import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
|
||||||
|
|
@ -66,15 +70,15 @@ public class InterceptorConfigurerTests {
|
||||||
@Test
|
@Test
|
||||||
public void addInterceptor() {
|
public void addInterceptor() {
|
||||||
configurer.addInterceptor(interceptor1);
|
configurer.addInterceptor(interceptor1);
|
||||||
HandlerInterceptor[] interceptors = getInterceptorsForPath(null);
|
List<HandlerInterceptor> interceptors = getInterceptorsForPath(null);
|
||||||
assertArrayEquals(new HandlerInterceptor[] {interceptor1}, interceptors);
|
assertEquals(Arrays.asList(interceptor1), interceptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addInterceptors() {
|
public void addInterceptors() {
|
||||||
configurer.addInterceptors(interceptor1, interceptor2);
|
configurer.addInterceptors(interceptor1, interceptor2);
|
||||||
HandlerInterceptor[] interceptors = getInterceptorsForPath(null);
|
List<HandlerInterceptor> interceptors = getInterceptorsForPath(null);
|
||||||
assertArrayEquals(new HandlerInterceptor[] {interceptor1, interceptor2}, interceptors);
|
assertEquals(Arrays.asList(interceptor1, interceptor2), interceptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -82,35 +86,35 @@ public class InterceptorConfigurerTests {
|
||||||
configurer.mapInterceptor(new String[] {"/path1"}, interceptor1);
|
configurer.mapInterceptor(new String[] {"/path1"}, interceptor1);
|
||||||
configurer.mapInterceptor(new String[] {"/path2"}, interceptor2);
|
configurer.mapInterceptor(new String[] {"/path2"}, interceptor2);
|
||||||
|
|
||||||
assertArrayEquals(new HandlerInterceptor[] {interceptor1}, getInterceptorsForPath("/path1"));
|
assertEquals(Arrays.asList(interceptor1), getInterceptorsForPath("/path1"));
|
||||||
assertArrayEquals(new HandlerInterceptor[] {interceptor2}, getInterceptorsForPath("/path2"));
|
assertEquals(Arrays.asList(interceptor2), getInterceptorsForPath("/path2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void mapInterceptors() {
|
public void mapInterceptors() {
|
||||||
configurer.mapInterceptors(new String[] {"/path1"}, interceptor1, interceptor2);
|
configurer.mapInterceptors(new String[] {"/path1"}, interceptor1, interceptor2);
|
||||||
|
|
||||||
assertArrayEquals(new HandlerInterceptor[] {interceptor1, interceptor2}, getInterceptorsForPath("/path1"));
|
assertEquals(Arrays.asList(interceptor1, interceptor2), getInterceptorsForPath("/path1"));
|
||||||
assertArrayEquals(new HandlerInterceptor[] {}, getInterceptorsForPath("/path2"));
|
assertEquals(Arrays.asList(), getInterceptorsForPath("/path2"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addWebRequestInterceptor() throws Exception {
|
public void addWebRequestInterceptor() throws Exception {
|
||||||
configurer.addInterceptor(webRequestInterceptor1);
|
configurer.addInterceptor(webRequestInterceptor1);
|
||||||
HandlerInterceptor[] interceptors = getInterceptorsForPath(null);
|
List<HandlerInterceptor> interceptors = getInterceptorsForPath(null);
|
||||||
|
|
||||||
assertEquals(1, interceptors.length);
|
assertEquals(1, interceptors.size());
|
||||||
verifyAdaptedInterceptor(interceptors[0], webRequestInterceptor1);
|
verifyAdaptedInterceptor(interceptors.get(0), webRequestInterceptor1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void addWebRequestInterceptors() throws Exception {
|
public void addWebRequestInterceptors() throws Exception {
|
||||||
configurer.addInterceptors(webRequestInterceptor1, webRequestInterceptor2);
|
configurer.addInterceptors(webRequestInterceptor1, webRequestInterceptor2);
|
||||||
HandlerInterceptor[] interceptors = getInterceptorsForPath(null);
|
List<HandlerInterceptor> interceptors = getInterceptorsForPath(null);
|
||||||
|
|
||||||
assertEquals(2, interceptors.length);
|
assertEquals(2, interceptors.size());
|
||||||
verifyAdaptedInterceptor(interceptors[0], webRequestInterceptor1);
|
verifyAdaptedInterceptor(interceptors.get(0), webRequestInterceptor1);
|
||||||
verifyAdaptedInterceptor(interceptors[1], webRequestInterceptor2);
|
verifyAdaptedInterceptor(interceptors.get(1), webRequestInterceptor2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
@ -118,30 +122,36 @@ public class InterceptorConfigurerTests {
|
||||||
configurer.mapInterceptor(new String[] {"/path1"}, webRequestInterceptor1);
|
configurer.mapInterceptor(new String[] {"/path1"}, webRequestInterceptor1);
|
||||||
configurer.mapInterceptor(new String[] {"/path2"}, webRequestInterceptor2);
|
configurer.mapInterceptor(new String[] {"/path2"}, webRequestInterceptor2);
|
||||||
|
|
||||||
HandlerInterceptor[] interceptors = getInterceptorsForPath("/path1");
|
List<HandlerInterceptor> interceptors = getInterceptorsForPath("/path1");
|
||||||
assertEquals(1, interceptors.length);
|
assertEquals(1, interceptors.size());
|
||||||
verifyAdaptedInterceptor(interceptors[0], webRequestInterceptor1);
|
verifyAdaptedInterceptor(interceptors.get(0), webRequestInterceptor1);
|
||||||
|
|
||||||
interceptors = getInterceptorsForPath("/path2");
|
interceptors = getInterceptorsForPath("/path2");
|
||||||
assertEquals(1, interceptors.length);
|
assertEquals(1, interceptors.size());
|
||||||
verifyAdaptedInterceptor(interceptors[0], webRequestInterceptor2);
|
verifyAdaptedInterceptor(interceptors.get(0), webRequestInterceptor2);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void mapWebRequestInterceptor2() throws Exception {
|
public void mapWebRequestInterceptor2() throws Exception {
|
||||||
configurer.mapInterceptors(new String[] {"/path1"}, webRequestInterceptor1, webRequestInterceptor2);
|
configurer.mapInterceptors(new String[] {"/path1"}, webRequestInterceptor1, webRequestInterceptor2);
|
||||||
|
|
||||||
HandlerInterceptor[] interceptors = getInterceptorsForPath("/path1");
|
List<HandlerInterceptor> interceptors = getInterceptorsForPath("/path1");
|
||||||
assertEquals(2, interceptors.length);
|
assertEquals(2, interceptors.size());
|
||||||
verifyAdaptedInterceptor(interceptors[0], webRequestInterceptor1);
|
verifyAdaptedInterceptor(interceptors.get(0), webRequestInterceptor1);
|
||||||
verifyAdaptedInterceptor(interceptors[1], webRequestInterceptor2);
|
verifyAdaptedInterceptor(interceptors.get(1), webRequestInterceptor2);
|
||||||
|
|
||||||
assertEquals(0, getInterceptorsForPath("/path2").length);
|
assertEquals(0, getInterceptorsForPath("/path2").size());
|
||||||
}
|
}
|
||||||
|
|
||||||
private HandlerInterceptor[] getInterceptorsForPath(String lookupPath) {
|
private List<HandlerInterceptor> getInterceptorsForPath(String lookupPath) {
|
||||||
MappedInterceptors mappedInterceptors = new MappedInterceptors(configurer.getInterceptors());
|
PathMatcher pathMatcher = new AntPathMatcher();
|
||||||
return mappedInterceptors.getInterceptors(lookupPath, new AntPathMatcher());
|
List<HandlerInterceptor> result = new ArrayList<HandlerInterceptor>();
|
||||||
|
for (MappedInterceptor interceptor : configurer.getInterceptors()) {
|
||||||
|
if (interceptor.matches(lookupPath, pathMatcher)) {
|
||||||
|
result.add(interceptor.getInterceptor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void verifyAdaptedInterceptor(HandlerInterceptor interceptor, TestWebRequestInterceptor webInterceptor)
|
private void verifyAdaptedInterceptor(HandlerInterceptor interceptor, TestWebRequestInterceptor webInterceptor)
|
||||||
|
|
|
||||||
|
|
@ -16,16 +16,25 @@
|
||||||
|
|
||||||
package org.springframework.web.servlet.config.annotation;
|
package org.springframework.web.servlet.config.annotation;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.capture;
|
||||||
|
import static org.easymock.EasyMock.expect;
|
||||||
|
import static org.easymock.EasyMock.replay;
|
||||||
|
import static org.easymock.EasyMock.verify;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.easymock.Capture;
|
import org.easymock.Capture;
|
||||||
import org.easymock.EasyMock;
|
import org.easymock.EasyMock;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import org.springframework.format.support.FormattingConversionService;
|
import org.springframework.format.support.FormattingConversionService;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||||
|
|
@ -46,9 +55,6 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||||
|
|
||||||
import static org.easymock.EasyMock.*;
|
|
||||||
import static org.junit.Assert.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A test fixture for WebMvcConfiguration tests.
|
* A test fixture for WebMvcConfiguration tests.
|
||||||
*
|
*
|
||||||
|
|
@ -67,17 +73,17 @@ public class WebMvcConfigurationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void annotationHandlerAdapter() {
|
public void annotationHandlerAdapter() throws Exception {
|
||||||
|
Capture<List<HttpMessageConverter<?>>> converters = new Capture<List<HttpMessageConverter<?>>>();
|
||||||
Capture<FormattingConversionService> conversionService = new Capture<FormattingConversionService>();
|
Capture<FormattingConversionService> conversionService = new Capture<FormattingConversionService>();
|
||||||
Capture<List<HandlerMethodArgumentResolver>> resolvers = new Capture<List<HandlerMethodArgumentResolver>>();
|
Capture<List<HandlerMethodArgumentResolver>> resolvers = new Capture<List<HandlerMethodArgumentResolver>>();
|
||||||
Capture<List<HandlerMethodReturnValueHandler>> handlers = new Capture<List<HandlerMethodReturnValueHandler>>();
|
Capture<List<HandlerMethodReturnValueHandler>> handlers = new Capture<List<HandlerMethodReturnValueHandler>>();
|
||||||
Capture<List<HttpMessageConverter<?>>> converters = new Capture<List<HttpMessageConverter<?>>>();
|
|
||||||
|
|
||||||
|
configurer.configureMessageConverters(capture(converters));
|
||||||
expect(configurer.getValidator()).andReturn(null);
|
expect(configurer.getValidator()).andReturn(null);
|
||||||
configurer.addFormatters(capture(conversionService));
|
configurer.addFormatters(capture(conversionService));
|
||||||
configurer.addArgumentResolvers(capture(resolvers));
|
configurer.addArgumentResolvers(capture(resolvers));
|
||||||
configurer.addReturnValueHandlers(capture(handlers));
|
configurer.addReturnValueHandlers(capture(handlers));
|
||||||
configurer.configureMessageConverters(capture(converters));
|
|
||||||
replay(configurer);
|
replay(configurer);
|
||||||
|
|
||||||
mvcConfiguration.setConfigurers(Arrays.asList(configurer));
|
mvcConfiguration.setConfigurers(Arrays.asList(configurer));
|
||||||
|
|
@ -107,7 +113,8 @@ public class WebMvcConfigurationTests {
|
||||||
converters.add(new StringHttpMessageConverter());
|
converters.add(new StringHttpMessageConverter());
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
mvcConfiguration.setConfigurers(configurers );
|
mvcConfiguration = new WebMvcConfiguration();
|
||||||
|
mvcConfiguration.setConfigurers(configurers);
|
||||||
|
|
||||||
adapter = mvcConfiguration.requestMappingHandlerAdapter();
|
adapter = mvcConfiguration.requestMappingHandlerAdapter();
|
||||||
assertEquals("Only one custom converter should be registered", 1, adapter.getMessageConverters().size());
|
assertEquals("Only one custom converter should be registered", 1, adapter.getMessageConverters().size());
|
||||||
|
|
@ -187,7 +194,7 @@ public class WebMvcConfigurationTests {
|
||||||
hm.setApplicationContext(context);
|
hm.setApplicationContext(context);
|
||||||
HandlerExecutionChain chain = hm.getHandler(request);
|
HandlerExecutionChain chain = hm.getHandler(request);
|
||||||
assertNotNull("No chain returned", chain);
|
assertNotNull("No chain returned", chain);
|
||||||
assertNotNull("Expected at one default converter", chain.getInterceptors());
|
assertNotNull("Expected at least one default converter", chain.getInterceptors());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
|
|
|
||||||
|
|
@ -140,19 +140,25 @@ public class RequestMappingHandlerMappingTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void mappedInterceptors() {
|
public void mappedInterceptors() throws Exception {
|
||||||
String path = "/handle";
|
String path = "/foo";
|
||||||
HandlerInterceptor interceptor = new HandlerInterceptorAdapter() {};
|
HandlerInterceptor interceptor = new HandlerInterceptorAdapter() {};
|
||||||
MappedInterceptor mappedInterceptor = new MappedInterceptor(new String[] {path}, interceptor);
|
MappedInterceptor mappedInterceptor = new MappedInterceptor(new String[] {path}, interceptor);
|
||||||
|
|
||||||
mapping.setMappedInterceptors(new MappedInterceptor[] { mappedInterceptor });
|
StaticApplicationContext context = new StaticApplicationContext();
|
||||||
|
context.registerSingleton("handler", handler.getClass());
|
||||||
|
|
||||||
HandlerExecutionChain chain = mapping.getHandlerExecutionChain(handler, new MockHttpServletRequest("GET", path));
|
mapping = new RequestMappingHandlerMapping();
|
||||||
|
mapping.setInterceptors(new Object[] { mappedInterceptor });
|
||||||
|
mapping.setApplicationContext(context);
|
||||||
|
|
||||||
|
HandlerExecutionChain chain = mapping.getHandler(new MockHttpServletRequest("GET", path));
|
||||||
|
assertNotNull(chain);
|
||||||
assertNotNull(chain.getInterceptors());
|
assertNotNull(chain.getInterceptors());
|
||||||
assertSame(interceptor, chain.getInterceptors()[0]);
|
assertSame(interceptor, chain.getInterceptors()[0]);
|
||||||
|
|
||||||
chain = mapping.getHandlerExecutionChain(handler, new MockHttpServletRequest("GET", "/invalid"));
|
chain = mapping.getHandler(new MockHttpServletRequest("GET", "/invalid"));
|
||||||
assertNull(chain.getInterceptors());
|
assertNull(chain);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue