Rename EnableMvcConfiguration->EnableWebMvc, refine method names in WebMvcConfigurer, fix issue with MappedInterceptors
This commit is contained in:
parent
c8bc54e0cc
commit
726e920857
|
|
@ -34,7 +34,7 @@ import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler
|
|||
* by the Servlet container's default servlet.
|
||||
*
|
||||
* <p>It is important the configured handler remains last in the order of all {@link HandlerMapping} instances in
|
||||
* the Spring MVC web application context. That is is the case if relying on @{@link EnableMvcConfiguration}.
|
||||
* the Spring MVC web application context. That is is the case if relying on @{@link EnableWebMvc}.
|
||||
* However, if you register your own HandlerMapping instance sure to set its "order" property to a value lower
|
||||
* than that of the {@link DefaultServletHttpRequestHandler}, which is {@link Integer#MAX_VALUE}.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -30,28 +30,28 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||
* in @{@link Controller} classes.
|
||||
* <pre>
|
||||
* @Configuration
|
||||
* @EnableMvcConfiguration
|
||||
* @EnableWebMvc
|
||||
* @ComponentScan(
|
||||
* basePackageClasses = { MyMvcConfiguration.class },
|
||||
* basePackageClasses = { MyConfiguration.class },
|
||||
* excludeFilters = { @Filter(type = FilterType.ANNOTATION, value = Configuration.class) }
|
||||
* )
|
||||
* public class MyMvcConfiguration {
|
||||
* public class MyConfiguration {
|
||||
*
|
||||
* }
|
||||
* </pre>
|
||||
* <p>To customize the imported configuration you simply implement {@link MvcConfigurer}, or more likely extend
|
||||
* {@link MvcConfigurerSupport} overriding selected methods only. The most obvious place to do this is
|
||||
* the @{@link Configuration} class that enabled the Spring MVC configuration via @{@link EnableMvcConfiguration}.
|
||||
* However any @{@link Configuration} class and more generally any Spring bean can implement {@link MvcConfigurer}
|
||||
* <p>To customize the imported configuration you simply implement {@link WebMvcConfigurer}, or more likely extend
|
||||
* {@link WebMvcConfigurerAdapter} overriding selected methods only. The most obvious place to do this is
|
||||
* the @{@link Configuration} class that enabled the Spring MVC configuration via @{@link EnableWebMvc}.
|
||||
* However any @{@link Configuration} class and more generally any Spring bean can implement {@link WebMvcConfigurer}
|
||||
* to be detected and given an opportunity to customize Spring MVC configuration at startup.
|
||||
* <pre>
|
||||
* @Configuration
|
||||
* @EnableMvcConfiguration
|
||||
* @EnableWebMvc
|
||||
* @ComponentScan(
|
||||
* basePackageClasses = { MyMvcConfiguration.class },
|
||||
* basePackageClasses = { MyConfiguration.class },
|
||||
* excludeFilters = { @Filter(type = FilterType.ANNOTATION, value = Configuration.class) }
|
||||
* )
|
||||
* public class MyMvcConfiguration extends MvcConfigurerSupport {
|
||||
* public class MyConfiguration extends WebMvcConfigurerAdapter {
|
||||
*
|
||||
* @Override
|
||||
* public void registerFormatters(FormatterRegistry formatterRegistry) {
|
||||
|
|
@ -68,8 +68,8 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @see MvcConfigurer
|
||||
* @see MvcConfigurerSupport
|
||||
* @see WebMvcConfigurer
|
||||
* @see WebMvcConfigurerAdapter
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Rossen Stoyanchev
|
||||
|
|
@ -78,6 +78,6 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
@Import(MvcConfiguration.class)
|
||||
public @interface EnableMvcConfiguration {
|
||||
@Import(WebMvcConfiguration.class)
|
||||
public @interface EnableWebMvc {
|
||||
}
|
||||
|
|
@ -24,7 +24,6 @@ import org.springframework.web.context.request.WebRequestInterceptor;
|
|||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.handler.MappedInterceptor;
|
||||
import org.springframework.web.servlet.handler.MappedInterceptors;
|
||||
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
|
||||
|
||||
/**
|
||||
|
|
@ -117,10 +116,10 @@ public class InterceptorConfigurer {
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link MappedInterceptors} instance with all registered interceptors.
|
||||
* Returns all registered interceptors.
|
||||
*/
|
||||
protected MappedInterceptors getMappedInterceptors() {
|
||||
return new MappedInterceptors(mappedInterceptors.toArray(new MappedInterceptor[mappedInterceptors.size()]));
|
||||
protected MappedInterceptor[] getInterceptors() {
|
||||
return mappedInterceptors.toArray(new MappedInterceptor[mappedInterceptors.size()]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@ import org.springframework.web.servlet.HandlerMapping;
|
|||
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;
|
||||
|
|
@ -72,10 +73,10 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv
|
|||
/**
|
||||
* Provides default configuration for Spring MVC applications. Registers Spring MVC infrastructure components to be
|
||||
* detected by the {@link DispatcherServlet}. Further below is a list of registered instances. This configuration is
|
||||
* enabled through the {@link EnableMvcConfiguration} annotation.
|
||||
* enabled through the {@link EnableWebMvc} annotation.
|
||||
*
|
||||
* <p>A number of options are available for customizing the default configuration provided by this class.
|
||||
* See {@link EnableMvcConfiguration} and {@link MvcConfigurer} for details.
|
||||
* See {@link EnableWebMvc} and {@link WebMvcConfigurer} for details.
|
||||
*
|
||||
* <p>Registers these handler mappings:
|
||||
* <ul>
|
||||
|
|
@ -87,7 +88,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 MvcConfigurer}.
|
||||
* hence no effect until explicitly configured via {@link WebMvcConfigurer}.
|
||||
*
|
||||
* <p>Registers these handler adapters:
|
||||
* <ul>
|
||||
|
|
@ -110,23 +111,23 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv
|
|||
* <li>{@link MappedInterceptors} containing a list Spring MVC lifecycle interceptors.
|
||||
* </ul>
|
||||
*
|
||||
* @see EnableMvcConfiguration
|
||||
* @see MvcConfigurer
|
||||
* @see EnableWebMvc
|
||||
* @see WebMvcConfigurer
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*/
|
||||
@Configuration
|
||||
class MvcConfiguration implements ApplicationContextAware, ServletContextAware {
|
||||
class WebMvcConfiguration implements ApplicationContextAware, ServletContextAware {
|
||||
|
||||
private final MvcConfigurerComposite configurers = new MvcConfigurerComposite();
|
||||
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
|
||||
|
||||
private ServletContext servletContext;
|
||||
|
||||
private ApplicationContext applicationContext;
|
||||
|
||||
@Autowired(required = false)
|
||||
public void setConfigurers(List<MvcConfigurer> configurers) {
|
||||
public void setConfigurers(List<WebMvcConfigurer> configurers) {
|
||||
this.configurers.addConfigurers(configurers);
|
||||
}
|
||||
|
||||
|
|
@ -139,29 +140,41 @@ class MvcConfiguration implements ApplicationContextAware, ServletContextAware {
|
|||
}
|
||||
|
||||
@Bean
|
||||
RequestMappingHandlerMapping requestMappingHandlerMapping() {
|
||||
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
|
||||
RequestMappingHandlerMapping mapping = new RequestMappingHandlerMapping();
|
||||
mapping.setMappedInterceptors(getMappedInterceptors());
|
||||
mapping.setOrder(0);
|
||||
return mapping;
|
||||
}
|
||||
|
||||
@Bean
|
||||
HandlerMapping viewControllerHandlerMapping() {
|
||||
ViewControllerConfigurer configurer = new ViewControllerConfigurer();
|
||||
configurer.setOrder(1);
|
||||
configurers.addViewControllers(configurer);
|
||||
return configurer.getHandlerMapping();
|
||||
private MappedInterceptor[] getMappedInterceptors() {
|
||||
InterceptorConfigurer configurer = new InterceptorConfigurer();
|
||||
configurers.configureInterceptors(configurer);
|
||||
configurer.addInterceptor(new ConversionServiceExposingInterceptor(conversionService()));
|
||||
return configurer.getInterceptors();
|
||||
}
|
||||
|
||||
@Bean
|
||||
BeanNameUrlHandlerMapping beanNameHandlerMapping() {
|
||||
public HandlerMapping viewControllerHandlerMapping() {
|
||||
ViewControllerConfigurer configurer = new ViewControllerConfigurer();
|
||||
configurer.setOrder(1);
|
||||
configurers.configureViewControllers(configurer);
|
||||
|
||||
SimpleUrlHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
||||
handlerMapping.setMappedInterceptors(getMappedInterceptors());
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public BeanNameUrlHandlerMapping beanNameHandlerMapping() {
|
||||
BeanNameUrlHandlerMapping mapping = new BeanNameUrlHandlerMapping();
|
||||
mapping.setOrder(2);
|
||||
mapping.setMappedInterceptors(getMappedInterceptors());
|
||||
return mapping;
|
||||
}
|
||||
|
||||
@Bean
|
||||
HandlerMapping resourceHandlerMapping() {
|
||||
public HandlerMapping resourceHandlerMapping() {
|
||||
ResourceConfigurer configurer = new ResourceConfigurer(applicationContext, servletContext);
|
||||
configurer.setOrder(Integer.MAX_VALUE-1);
|
||||
configurers.configureResourceHandling(configurer);
|
||||
|
|
@ -169,14 +182,14 @@ class MvcConfiguration implements ApplicationContextAware, ServletContextAware {
|
|||
}
|
||||
|
||||
@Bean
|
||||
HandlerMapping defaultServletHandlerMapping() {
|
||||
public HandlerMapping defaultServletHandlerMapping() {
|
||||
DefaultServletHandlerConfigurer configurer = new DefaultServletHandlerConfigurer(servletContext);
|
||||
configurers.configureDefaultServletHandling(configurer);
|
||||
return configurer.getHandlerMapping();
|
||||
}
|
||||
|
||||
@Bean
|
||||
RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
|
||||
public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
|
||||
RequestMappingHandlerAdapter adapter = new RequestMappingHandlerAdapter();
|
||||
|
||||
ConfigurableWebBindingInitializer bindingInitializer = new ConfigurableWebBindingInitializer();
|
||||
|
|
@ -185,29 +198,32 @@ class MvcConfiguration implements ApplicationContextAware, ServletContextAware {
|
|||
adapter.setWebBindingInitializer(bindingInitializer);
|
||||
|
||||
List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<HandlerMethodArgumentResolver>();
|
||||
configurers.addCustomArgumentResolvers(argumentResolvers);
|
||||
configurers.addArgumentResolvers(argumentResolvers);
|
||||
adapter.setCustomArgumentResolvers(argumentResolvers);
|
||||
|
||||
List<HandlerMethodReturnValueHandler> returnValueHandlers = new ArrayList<HandlerMethodReturnValueHandler>();
|
||||
configurers.addCustomReturnValueHandlers(returnValueHandlers);
|
||||
configurers.addReturnValueHandlers(returnValueHandlers);
|
||||
adapter.setCustomReturnValueHandlers(returnValueHandlers);
|
||||
|
||||
List<HttpMessageConverter<?>> converters = getDefaultHttpMessageConverters();
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
|
||||
configurers.configureMessageConverters(converters);
|
||||
if (converters.size() == 0) {
|
||||
addDefaultHttpMessageConverters(converters);
|
||||
}
|
||||
adapter.setMessageConverters(converters);
|
||||
|
||||
return adapter;
|
||||
}
|
||||
|
||||
@Bean(name="mvcConversionService")
|
||||
FormattingConversionService conversionService() {
|
||||
public FormattingConversionService conversionService() {
|
||||
FormattingConversionService conversionService = new DefaultFormattingConversionService();
|
||||
configurers.registerFormatters(conversionService);
|
||||
configurers.addFormatters(conversionService);
|
||||
return conversionService;
|
||||
}
|
||||
|
||||
@Bean(name="mvcValidator")
|
||||
Validator validator() {
|
||||
public Validator validator() {
|
||||
Validator validator = configurers.getValidator();
|
||||
if (validator != null) {
|
||||
return validator;
|
||||
|
|
@ -216,7 +232,7 @@ class MvcConfiguration implements ApplicationContextAware, ServletContextAware {
|
|||
Class<?> clazz;
|
||||
try {
|
||||
String className = "org.springframework.validation.beanvalidation.LocalValidatorFactoryBean";
|
||||
clazz = ClassUtils.forName(className, MvcConfiguration.class.getClassLoader());
|
||||
clazz = ClassUtils.forName(className, WebMvcConfiguration.class.getClassLoader());
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new BeanInitializationException("Could not find default validator");
|
||||
} catch (LinkageError e) {
|
||||
|
|
@ -236,11 +252,10 @@ class MvcConfiguration implements ApplicationContextAware, ServletContextAware {
|
|||
}
|
||||
}
|
||||
|
||||
private List<HttpMessageConverter<?>> getDefaultHttpMessageConverters() {
|
||||
private void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
|
||||
stringConverter.setWriteAcceptCharset(false);
|
||||
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
|
||||
converters.add(new ByteArrayHttpMessageConverter());
|
||||
converters.add(stringConverter);
|
||||
converters.add(new ResourceHttpMessageConverter());
|
||||
|
|
@ -258,27 +273,28 @@ class MvcConfiguration implements ApplicationContextAware, ServletContextAware {
|
|||
converters.add(new AtomFeedHttpMessageConverter());
|
||||
converters.add(new RssChannelHttpMessageConverter());
|
||||
}
|
||||
|
||||
return converters;
|
||||
}
|
||||
|
||||
@Bean
|
||||
HttpRequestHandlerAdapter httpRequestHandlerAdapter() {
|
||||
public HttpRequestHandlerAdapter httpRequestHandlerAdapter() {
|
||||
return new HttpRequestHandlerAdapter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
SimpleControllerHandlerAdapter simpleControllerHandlerAdapter() {
|
||||
public SimpleControllerHandlerAdapter simpleControllerHandlerAdapter() {
|
||||
return new SimpleControllerHandlerAdapter();
|
||||
}
|
||||
|
||||
@Bean
|
||||
HandlerExceptionResolver handlerExceptionResolver() throws Exception {
|
||||
public HandlerExceptionResolver handlerExceptionResolver() throws Exception {
|
||||
List<HandlerExceptionResolver> resolvers = new ArrayList<HandlerExceptionResolver>();
|
||||
configurers.configureHandlerExceptionResolvers(resolvers);
|
||||
|
||||
if (resolvers.size() == 0) {
|
||||
resolvers.add(createExceptionHandlerExceptionResolver());
|
||||
resolvers.add(new ResponseStatusExceptionResolver());
|
||||
resolvers.add(new DefaultHandlerExceptionResolver());
|
||||
configurers.configureHandlerExceptionResolvers(resolvers);
|
||||
}
|
||||
|
||||
HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
|
||||
composite.setOrder(0);
|
||||
|
|
@ -288,22 +304,17 @@ class MvcConfiguration implements ApplicationContextAware, ServletContextAware {
|
|||
|
||||
private HandlerExceptionResolver createExceptionHandlerExceptionResolver() throws Exception {
|
||||
ExceptionHandlerExceptionResolver resolver = new ExceptionHandlerExceptionResolver();
|
||||
|
||||
List<HttpMessageConverter<?>> converters = getDefaultHttpMessageConverters();
|
||||
configurers.configureMessageConverters(converters);
|
||||
resolver.setMessageConverters(converters);
|
||||
resolver.setOrder(0);
|
||||
|
||||
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
|
||||
configurers.configureMessageConverters(converters);
|
||||
if (converters.size() == 0) {
|
||||
addDefaultHttpMessageConverters(converters);
|
||||
}
|
||||
resolver.setMessageConverters(converters);
|
||||
|
||||
resolver.afterPropertiesSet();
|
||||
return resolver;
|
||||
}
|
||||
|
||||
@Bean
|
||||
MappedInterceptors mappedInterceptors() {
|
||||
InterceptorConfigurer configurer = new InterceptorConfigurer();
|
||||
configurer.addInterceptor(new ConversionServiceExposingInterceptor(conversionService()));
|
||||
configurers.addInterceptors(configurer);
|
||||
return configurer.getMappedInterceptors();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -36,12 +36,12 @@ import com.sun.corba.se.impl.presentation.rmi.ExceptionHandler;
|
|||
|
||||
/**
|
||||
* Defines options for customizing or adding to the default Spring MVC configuration enabled through the use
|
||||
* of @{@link EnableMvcConfiguration}. The @{@link Configuration} class annotated with @{@link EnableMvcConfiguration}
|
||||
* of @{@link EnableWebMvc}. The @{@link Configuration} class annotated with @{@link EnableWebMvc}
|
||||
* is the most obvious place to implement this interface. However all @{@link Configuration} classes and more generally
|
||||
* all Spring beans that implement this interface will be detected at startup and given a chance to customize Spring
|
||||
* MVC configuration provided it is enabled through @{@link EnableMvcConfiguration}.
|
||||
* MVC configuration provided it is enabled through @{@link EnableWebMvc}.
|
||||
*
|
||||
* <p>Implementations of this interface will find it convenient to extend {@link MvcConfigurerSupport} that
|
||||
* <p>Implementations of this interface will find it convenient to extend {@link WebMvcConfigurerAdapter} that
|
||||
* provides default method implementations and allows overriding only methods of interest.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
|
|
@ -49,17 +49,18 @@ import com.sun.corba.se.impl.presentation.rmi.ExceptionHandler;
|
|||
* @author David Syer
|
||||
* @since 3.1
|
||||
*/
|
||||
public interface MvcConfigurer {
|
||||
public interface WebMvcConfigurer {
|
||||
|
||||
/**
|
||||
* Register application-specific {@link Converter}s and {@link Formatter}s for use in Spring MVC.
|
||||
* Add {@link Converter}s and {@link Formatter}s in addition to the ones registered by default.
|
||||
*/
|
||||
void registerFormatters(FormatterRegistry formatterRegistry);
|
||||
void addFormatters(FormatterRegistry formatterRegistry);
|
||||
|
||||
/**
|
||||
* Customize the list of {@link HttpMessageConverter}s to use when resolving method arguments or handling
|
||||
* return values from @{@link RequestMapping} and @{@link ExceptionHandler} methods.
|
||||
* @param converters the list of converters, initially populated with the default set of converters
|
||||
* Configure the list of {@link HttpMessageConverter}s to use when resolving method arguments or handling
|
||||
* return values in @{@link RequestMapping} and @{@link ExceptionHandler} methods.
|
||||
* Specifying custom converters overrides the converters registered by default.
|
||||
* @param converters a list to add message converters to
|
||||
*/
|
||||
void configureMessageConverters(List<HttpMessageConverter<?>> converters);
|
||||
|
||||
|
|
@ -71,37 +72,43 @@ public interface MvcConfigurer {
|
|||
Validator getValidator();
|
||||
|
||||
/**
|
||||
* Add custom {@link HandlerMethodArgumentResolver}s to use for resolving argument values
|
||||
* on @{@link RequestMapping} and @{@link ExceptionHandler} methods.
|
||||
* Add custom {@link HandlerMethodArgumentResolver}s to use in addition to the ones 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
|
||||
* argument resolvers are not customizable without configuring RequestMappingHandlerAdapter directly.
|
||||
* @param argumentResolvers the list of custom converters, initially empty
|
||||
*/
|
||||
void addCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers);
|
||||
void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers);
|
||||
|
||||
/**
|
||||
* Add custom {@link HandlerMethodReturnValueHandler}s to use for handling return values
|
||||
* from @{@link RequestMapping} and @{@link ExceptionHandler} methods.
|
||||
* Add custom {@link HandlerMethodReturnValueHandler}s to in addition to the ones 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 (e.g. {@code @ResponseBody}, {@code @ModelAttribute}, etc.). Those
|
||||
* handlers are not customizable without configuring RequestMappingHandlerAdapter directly.
|
||||
* @param returnValueHandlers the list of custom handlers, initially empty
|
||||
*/
|
||||
void addCustomReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers);
|
||||
void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers);
|
||||
|
||||
/**
|
||||
* Customize the list of {@link HandlerExceptionResolver}s to use for handling controller exceptions.
|
||||
* @param exceptionResolvers the list of resolvers, initially populated with the default set of resolvers
|
||||
* Configure the list of {@link HandlerExceptionResolver}s to use for handling unresolved controller exceptions.
|
||||
* Specifying exception resolvers overrides the ones registered by default.
|
||||
* @param exceptionResolvers a list to add exception resolvers to
|
||||
*/
|
||||
void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers);
|
||||
|
||||
/**
|
||||
* Add Spring MVC interceptors. Interceptors can be of type {@link HandlerInterceptor} or
|
||||
* Configure the Spring MVC interceptors to use. Interceptors can be of type {@link HandlerInterceptor} or
|
||||
* {@link WebRequestInterceptor}. They allow requests to be pre/post processed before/after controller
|
||||
* invocation. Interceptors can be registered to apply to all requests or limited to a set of path patterns.
|
||||
* @see InterceptorConfigurer
|
||||
*/
|
||||
void addInterceptors(InterceptorConfigurer interceptorConfigurer);
|
||||
void configureInterceptors(InterceptorConfigurer interceptorConfigurer);
|
||||
|
||||
/**
|
||||
* Map URL paths to view names. This is convenient when a request can be rendered without a controller.
|
||||
* 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 addViewControllers(ViewControllerConfigurer viewControllerConfigurer);
|
||||
void configureViewControllers(ViewControllerConfigurer viewControllerConfigurer);
|
||||
|
||||
/**
|
||||
* Configure a handler for serving static resources such as images, js, and, css files through Spring MVC
|
||||
|
|
@ -22,22 +22,23 @@ import org.springframework.format.FormatterRegistry;
|
|||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
|
||||
/**
|
||||
* An abstract class with empty method implementations of the {@link MvcConfigurer} interface for a simplified
|
||||
* implementation of {@link MvcConfigurer} so that subclasses can override selected methods only.
|
||||
* An abstract class with empty method implementations of {@link WebMvcConfigurer}.
|
||||
* Subclasses can override only the methods they need.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*/
|
||||
public abstract class MvcConfigurerSupport implements MvcConfigurer {
|
||||
public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void registerFormatters(FormatterRegistry formatterRegistry) {
|
||||
public void addFormatters(FormatterRegistry formatterRegistry) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -47,13 +48,6 @@ public abstract class MvcConfigurerSupport implements MvcConfigurer {
|
|||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void configureValidator(Validator validator) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation returns {@code null}
|
||||
|
|
@ -66,7 +60,14 @@ public abstract class MvcConfigurerSupport implements MvcConfigurer {
|
|||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void addCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -80,14 +81,14 @@ public abstract class MvcConfigurerSupport implements MvcConfigurer {
|
|||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void addInterceptors(InterceptorConfigurer interceptorConfigurer) {
|
||||
public void configureInterceptors(InterceptorConfigurer interceptorConfigurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void addViewControllers(ViewControllerConfigurer viewControllerConfigurer) {
|
||||
public void configureViewControllers(ViewControllerConfigurer viewControllerConfigurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -29,78 +29,78 @@ import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
|||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
|
||||
/**
|
||||
* An {@link MvcConfigurer} implementation that delegates to other {@link MvcConfigurer} instances.
|
||||
* An {@link WebMvcConfigurer} implementation that delegates to other {@link WebMvcConfigurer} instances.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*/
|
||||
class MvcConfigurerComposite implements MvcConfigurer {
|
||||
class WebMvcConfigurerComposite implements WebMvcConfigurer {
|
||||
|
||||
private final List<MvcConfigurer> configurers = new ArrayList<MvcConfigurer>();
|
||||
private final List<WebMvcConfigurer> configurers = new ArrayList<WebMvcConfigurer>();
|
||||
|
||||
void addConfigurers(List<MvcConfigurer> configurers) {
|
||||
public void addConfigurers(List<WebMvcConfigurer> configurers) {
|
||||
if (configurers != null) {
|
||||
this.configurers.addAll(configurers);
|
||||
}
|
||||
}
|
||||
|
||||
public void registerFormatters(FormatterRegistry formatterRegistry) {
|
||||
for (MvcConfigurer configurer : configurers) {
|
||||
configurer.registerFormatters(formatterRegistry);
|
||||
public void addFormatters(FormatterRegistry formatterRegistry) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.addFormatters(formatterRegistry);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
for (MvcConfigurer configurer : configurers) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.configureMessageConverters(converters);
|
||||
}
|
||||
}
|
||||
|
||||
public void addCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
for (MvcConfigurer configurer : configurers) {
|
||||
configurer.addCustomArgumentResolvers(argumentResolvers);
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.addArgumentResolvers(argumentResolvers);
|
||||
}
|
||||
}
|
||||
|
||||
public void addCustomReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
||||
for (MvcConfigurer configurer : configurers) {
|
||||
configurer.addCustomReturnValueHandlers(returnValueHandlers);
|
||||
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.addReturnValueHandlers(returnValueHandlers);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||
for (MvcConfigurer configurer : configurers) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.configureHandlerExceptionResolvers(exceptionResolvers);
|
||||
}
|
||||
}
|
||||
|
||||
public void addInterceptors(InterceptorConfigurer interceptorRegistry) {
|
||||
for (MvcConfigurer configurer : configurers) {
|
||||
configurer.addInterceptors(interceptorRegistry);
|
||||
public void configureInterceptors(InterceptorConfigurer interceptorRegistry) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.configureInterceptors(interceptorRegistry);
|
||||
}
|
||||
}
|
||||
|
||||
public void addViewControllers(ViewControllerConfigurer viewControllerConfigurer) {
|
||||
for (MvcConfigurer configurer : configurers) {
|
||||
configurer.addViewControllers(viewControllerConfigurer);
|
||||
public void configureViewControllers(ViewControllerConfigurer viewControllerConfigurer) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.configureViewControllers(viewControllerConfigurer);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureResourceHandling(ResourceConfigurer resourceConfigurer) {
|
||||
for (MvcConfigurer configurer : configurers) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.configureResourceHandling(resourceConfigurer);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer handlerConfigurer) {
|
||||
for (MvcConfigurer configurer : configurers) {
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
configurer.configureDefaultServletHandling(handlerConfigurer);
|
||||
}
|
||||
}
|
||||
|
||||
public Validator getValidator() {
|
||||
Map<MvcConfigurer, Validator> validators = new HashMap<MvcConfigurer, Validator>();
|
||||
for (MvcConfigurer configurer : configurers) {
|
||||
Map<WebMvcConfigurer, Validator> validators = new HashMap<WebMvcConfigurer, Validator>();
|
||||
for (WebMvcConfigurer configurer : configurers) {
|
||||
Validator validator = configurer.getValidator();
|
||||
if (validator != null) {
|
||||
validators.put(configurer, validator);
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package org.springframework.web.servlet.handler;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
|
@ -10,7 +11,7 @@ import org.springframework.web.servlet.HandlerExceptionResolver;
|
|||
import org.springframework.web.servlet.ModelAndView;
|
||||
|
||||
/**
|
||||
* A {@link HandlerExceptionResolver} that delegates to a list of {@link HandlerExceptionResolver}s.
|
||||
* A {@link HandlerExceptionResolver} that delegates to a list of other {@link HandlerExceptionResolver}s.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
|
|
@ -29,10 +30,24 @@ public class HandlerExceptionResolverComposite implements HandlerExceptionResolv
|
|||
return this.order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the list of exception resolvers to delegate to.
|
||||
*/
|
||||
public void setExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||
this.resolvers = exceptionResolvers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of exception resolvers to delegate to.
|
||||
*/
|
||||
public List<HandlerExceptionResolver> getExceptionResolvers() {
|
||||
return Collections.unmodifiableList(resolvers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve the exception by iterating over the list of configured exception resolvers.
|
||||
* The first one to return a ModelAndView instance wins. Otherwise {@code null} is returned.
|
||||
*/
|
||||
public ModelAndView resolveException(HttpServletRequest request,
|
||||
HttpServletResponse response,
|
||||
Object handler,
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.springframework.util.AntPathMatcher;
|
|||
import org.springframework.web.context.request.WebRequest;
|
||||
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.handler.MappedInterceptors;
|
||||
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
|
||||
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
||||
import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
|
||||
|
|
@ -139,7 +140,8 @@ public class InterceptorConfigurerTests {
|
|||
}
|
||||
|
||||
private HandlerInterceptor[] getInterceptorsForPath(String lookupPath) {
|
||||
return configurer.getMappedInterceptors().getInterceptors(lookupPath, new AntPathMatcher());
|
||||
MappedInterceptors mappedInterceptors = new MappedInterceptors(configurer.getInterceptors());
|
||||
return mappedInterceptors.getInterceptors(lookupPath, new AntPathMatcher());
|
||||
}
|
||||
|
||||
private void verifyAdaptedInterceptor(HandlerInterceptor interceptor, TestWebRequestInterceptor webInterceptor)
|
||||
|
|
|
|||
|
|
@ -21,44 +21,55 @@ 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.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.easymock.Capture;
|
||||
import org.easymock.EasyMock;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
||||
import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite;
|
||||
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||
|
||||
/**
|
||||
* A test fixture with an {@link MvcConfiguration} and a mock {@link MvcConfigurer} for verifying delegation.
|
||||
* A test fixture for WebMvcConfiguration tests.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class MvcConfigurationTests {
|
||||
public class WebMvcConfigurationTests {
|
||||
|
||||
private MvcConfiguration mvcConfiguration;
|
||||
private WebMvcConfiguration mvcConfiguration;
|
||||
|
||||
private MvcConfigurer configurer;
|
||||
private WebMvcConfigurer configurer;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
configurer = EasyMock.createMock(MvcConfigurer.class);
|
||||
mvcConfiguration = new MvcConfiguration();
|
||||
mvcConfiguration.setConfigurers(Arrays.asList(configurer));
|
||||
configurer = EasyMock.createMock(WebMvcConfigurer.class);
|
||||
mvcConfiguration = new WebMvcConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -69,12 +80,13 @@ public class MvcConfigurationTests {
|
|||
Capture<List<HttpMessageConverter<?>>> converters = new Capture<List<HttpMessageConverter<?>>>();
|
||||
|
||||
expect(configurer.getValidator()).andReturn(null);
|
||||
configurer.registerFormatters(capture(conversionService));
|
||||
configurer.addCustomArgumentResolvers(capture(resolvers));
|
||||
configurer.addCustomReturnValueHandlers(capture(handlers));
|
||||
configurer.addFormatters(capture(conversionService));
|
||||
configurer.addArgumentResolvers(capture(resolvers));
|
||||
configurer.addReturnValueHandlers(capture(handlers));
|
||||
configurer.configureMessageConverters(capture(converters));
|
||||
replay(configurer);
|
||||
|
||||
mvcConfiguration.setConfigurers(Arrays.asList(configurer));
|
||||
RequestMappingHandlerAdapter adapter = mvcConfiguration.requestMappingHandlerAdapter();
|
||||
|
||||
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer();
|
||||
|
|
@ -89,11 +101,30 @@ public class MvcConfigurationTests {
|
|||
verify(configurer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configureMessageConverters() {
|
||||
RequestMappingHandlerAdapter adapter = mvcConfiguration.requestMappingHandlerAdapter();
|
||||
assertTrue("There should be at least two default converters ", adapter.getMessageConverters().size() > 1);
|
||||
|
||||
List<WebMvcConfigurer> configurers = new ArrayList<WebMvcConfigurer>();
|
||||
configurers.add(new WebMvcConfigurerAdapter() {
|
||||
@Override
|
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
converters.add(new StringHttpMessageConverter());
|
||||
}
|
||||
});
|
||||
mvcConfiguration.setConfigurers(configurers );
|
||||
|
||||
adapter = mvcConfiguration.requestMappingHandlerAdapter();
|
||||
assertEquals("Only one custom converter should be registered", 1, adapter.getMessageConverters().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getCustomValidator() {
|
||||
expect(configurer.getValidator()).andReturn(new LocalValidatorFactoryBean());
|
||||
replay(configurer);
|
||||
|
||||
mvcConfiguration.setConfigurers(Arrays.asList(configurer));
|
||||
mvcConfiguration.validator();
|
||||
|
||||
verify(configurer);
|
||||
|
|
@ -104,6 +135,7 @@ public class MvcConfigurationTests {
|
|||
expect(configurer.getValidator()).andReturn(null);
|
||||
replay(configurer);
|
||||
|
||||
mvcConfiguration.setConfigurers(Arrays.asList(configurer));
|
||||
mvcConfiguration.validator();
|
||||
|
||||
verify(configurer);
|
||||
|
|
@ -118,6 +150,7 @@ public class MvcConfigurationTests {
|
|||
configurer.configureHandlerExceptionResolvers(capture(exceptionResolvers));
|
||||
replay(configurer);
|
||||
|
||||
mvcConfiguration.setConfigurers(Arrays.asList(configurer));
|
||||
mvcConfiguration.handlerExceptionResolver();
|
||||
|
||||
assertEquals(3, exceptionResolvers.getValue().size());
|
||||
|
|
@ -129,4 +162,47 @@ public class MvcConfigurationTests {
|
|||
verify(configurer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configureExceptionResolvers() throws Exception {
|
||||
HandlerExceptionResolverComposite composite;
|
||||
|
||||
composite = (HandlerExceptionResolverComposite) mvcConfiguration.handlerExceptionResolver();
|
||||
assertTrue("Expected more than one exception resolver by default", composite.getExceptionResolvers().size() > 1);
|
||||
|
||||
List<WebMvcConfigurer> configurers = new ArrayList<WebMvcConfigurer>();
|
||||
configurers.add(new WebMvcConfigurerAdapter() {
|
||||
@Override
|
||||
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||
exceptionResolvers.add(new DefaultHandlerExceptionResolver());
|
||||
}
|
||||
});
|
||||
mvcConfiguration.setConfigurers(configurers);
|
||||
|
||||
composite = (HandlerExceptionResolverComposite) mvcConfiguration.handlerExceptionResolver();
|
||||
assertEquals("Only one custom converter is expected", 1, composite.getExceptionResolvers().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configureInterceptors() throws Exception {
|
||||
HttpServletRequest request = new MockHttpServletRequest("GET", "/");
|
||||
|
||||
StaticWebApplicationContext context = new StaticWebApplicationContext();
|
||||
context.registerSingleton("controller", TestHandler.class);
|
||||
|
||||
RequestMappingHandlerMapping hm = mvcConfiguration.requestMappingHandlerMapping();
|
||||
hm.setApplicationContext(context);
|
||||
HandlerExecutionChain chain = hm.getHandler(request);
|
||||
assertNotNull("Expected at one default converter", chain.getInterceptors());
|
||||
}
|
||||
|
||||
@Controller
|
||||
private static class TestHandler {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@RequestMapping("/")
|
||||
public void handle() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue