Introduce @EnableMvcConfiguration
This commit is contained in:
parent
01e5120a26
commit
446dfdbff2
|
|
@ -18,8 +18,6 @@ package org.springframework.web.servlet.config;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.w3c.dom.Element;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
import org.springframework.beans.factory.config.BeanDefinitionHolder;
|
||||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||||
|
|
@ -50,11 +48,12 @@ import org.springframework.web.bind.support.WebArgumentResolver;
|
||||||
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
|
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor;
|
||||||
import org.springframework.web.servlet.handler.MappedInterceptor;
|
import org.springframework.web.servlet.handler.MappedInterceptor;
|
||||||
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
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.RequestMappingHandlerMethodAdapter;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodExceptionResolver;
|
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodMapping;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodMapping;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;
|
import org.springframework.web.servlet.mvc.method.annotation.support.ServletWebArgumentResolverAdapter;
|
||||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||||
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@link BeanDefinitionParser} that parses the {@code annotation-driven} element to configure a Spring MVC web
|
* {@link BeanDefinitionParser} that parses the {@code annotation-driven} element to configure a Spring MVC web
|
||||||
|
|
@ -146,7 +145,7 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
mappedCsInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, csInterceptorDef);
|
mappedCsInterceptorDef.getConstructorArgumentValues().addIndexedArgumentValue(1, csInterceptorDef);
|
||||||
String mappedInterceptorName = parserContext.getReaderContext().registerWithGeneratedName(mappedCsInterceptorDef);
|
String mappedInterceptorName = parserContext.getReaderContext().registerWithGeneratedName(mappedCsInterceptorDef);
|
||||||
|
|
||||||
RootBeanDefinition methodExceptionResolver = new RootBeanDefinition(RequestMappingHandlerMethodExceptionResolver.class);
|
RootBeanDefinition methodExceptionResolver = new RootBeanDefinition(ExceptionHandlerExceptionResolver.class);
|
||||||
methodExceptionResolver.setSource(source);
|
methodExceptionResolver.setSource(source);
|
||||||
methodExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
methodExceptionResolver.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||||
methodExceptionResolver.getPropertyValues().add("messageConverters", messageConverters);
|
methodExceptionResolver.getPropertyValues().add("messageConverters", messageConverters);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,95 @@
|
||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import org.springframework.web.HttpRequestHandler;
|
||||||
|
import org.springframework.web.servlet.DispatcherServlet;
|
||||||
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||||
|
import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps with configuring a handler for serving static resources by forwarding to the Servlet container's default
|
||||||
|
* Servlet. This is commonly used when the {@link DispatcherServlet} is mapped to "/", which results in cleaner
|
||||||
|
* URLs (without a servlet prefix) but may need to still allow some requests (e.g. static resources) to be handled
|
||||||
|
* by the Servlet container's default servlet.
|
||||||
|
*
|
||||||
|
* <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}.
|
||||||
|
* 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}.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*
|
||||||
|
* @see ResourceConfigurer
|
||||||
|
*/
|
||||||
|
public class DefaultServletHandlerConfigurer {
|
||||||
|
|
||||||
|
private DefaultServletHttpRequestHandler requestHandler;
|
||||||
|
|
||||||
|
private final ServletContext servletContext;
|
||||||
|
|
||||||
|
public DefaultServletHandlerConfigurer(ServletContext servletContext) {
|
||||||
|
this.servletContext = servletContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable forwarding to the Servlet container default servlet. The {@link DefaultServletHttpRequestHandler}
|
||||||
|
* will try to auto-detect the default Servlet at startup using a list of known names. Alternatively, you can
|
||||||
|
* specify the name of the default Servlet, see {@link #enable(String)}.
|
||||||
|
*/
|
||||||
|
public void enable() {
|
||||||
|
enable(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enable forwarding to the Servlet container default servlet specifying explicitly the name of the default
|
||||||
|
* Servlet to forward static resource requests to. This is useful when the default Servlet cannot be detected
|
||||||
|
* (e.g. when using an unknown container or when it has been manually configured).
|
||||||
|
*/
|
||||||
|
public void enable(String defaultServletName) {
|
||||||
|
requestHandler = new DefaultServletHttpRequestHandler();
|
||||||
|
requestHandler.setDefaultServletName(defaultServletName);
|
||||||
|
requestHandler.setServletContext(servletContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a {@link SimpleUrlHandlerMapping} instance ordered at {@link Integer#MAX_VALUE} containing a
|
||||||
|
* {@link DefaultServletHttpRequestHandler} mapped to {@code /**}.
|
||||||
|
*/
|
||||||
|
protected SimpleUrlHandlerMapping getHandlerMapping() {
|
||||||
|
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
|
||||||
|
handlerMapping.setOrder(Integer.MAX_VALUE);
|
||||||
|
handlerMapping.setUrlMap(getUrlMap());
|
||||||
|
return handlerMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, HttpRequestHandler> getUrlMap() {
|
||||||
|
Map<String, HttpRequestHandler> urlMap = new HashMap<String, HttpRequestHandler>();
|
||||||
|
if (requestHandler != null) {
|
||||||
|
urlMap.put("/**", requestHandler);
|
||||||
|
}
|
||||||
|
return urlMap ;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,83 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2010 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.config.annotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Documented;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Import;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.servlet.DispatcherServlet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enables default Spring MVC configuration and registers Spring MVC infrastructure components expected by the
|
||||||
|
* {@link DispatcherServlet}. To use this annotation simply place it on an application @{@link Configuration} class
|
||||||
|
* and that will in turn import default Spring MVC configuration including support for annotated methods
|
||||||
|
* in @{@link Controller} classes.
|
||||||
|
* <pre>
|
||||||
|
* @Configuration
|
||||||
|
* @EnableMvcConfiguration
|
||||||
|
* @ComponentScan(
|
||||||
|
* basePackageClasses = { MyMvcConfiguration.class },
|
||||||
|
* excludeFilters = { @Filter(type = FilterType.ANNOTATION, value = Configuration.class) }
|
||||||
|
* )
|
||||||
|
* public class MyMvcConfiguration {
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
* </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}
|
||||||
|
* to be detected and given an opportunity to customize Spring MVC configuration at startup.
|
||||||
|
* <pre>
|
||||||
|
* @Configuration
|
||||||
|
* @EnableMvcConfiguration
|
||||||
|
* @ComponentScan(
|
||||||
|
* basePackageClasses = { MyMvcConfiguration.class },
|
||||||
|
* excludeFilters = { @Filter(type = FilterType.ANNOTATION, value = Configuration.class) }
|
||||||
|
* )
|
||||||
|
* public class MyMvcConfiguration extends MvcConfigurerSupport {
|
||||||
|
*
|
||||||
|
* @Override
|
||||||
|
* public void registerFormatters(FormatterRegistry formatterRegistry) {
|
||||||
|
* formatterRegistry.addConverter(new MyConverter());
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* @Override
|
||||||
|
* public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
|
* converters.add(new MyHttpMessageConverter());
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* ...
|
||||||
|
*
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
*
|
||||||
|
* @see MvcConfigurer
|
||||||
|
* @see MvcConfigurerSupport
|
||||||
|
*
|
||||||
|
* @author Dave Syer
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target(ElementType.TYPE)
|
||||||
|
@Documented
|
||||||
|
@Import(MvcConfiguration.class)
|
||||||
|
public @interface EnableMvcConfiguration {
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,126 @@
|
||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps with configuring an ordered set of Spring MVC interceptors of type {@link HandlerInterceptor} or
|
||||||
|
* {@link WebRequestInterceptor}. Registered interceptors will generally be detected by all {@link HandlerMapping}
|
||||||
|
* instances in a Spring MVC web application context. Interceptors can be added with a set of path patterns to
|
||||||
|
* which they should apply.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class InterceptorConfigurer {
|
||||||
|
|
||||||
|
private final List<MappedInterceptor> mappedInterceptors = new ArrayList<MappedInterceptor>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a {@link HandlerInterceptor} that should apply to any request.
|
||||||
|
*/
|
||||||
|
public void addInterceptor(HandlerInterceptor interceptor) {
|
||||||
|
register(null, interceptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a {@link WebRequestInterceptor} that should apply to any request.
|
||||||
|
*/
|
||||||
|
public void addInterceptor(WebRequestInterceptor interceptor) {
|
||||||
|
register(null, asHandlerInterceptorArray(interceptor));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add {@link HandlerInterceptor}s that should apply to any request.
|
||||||
|
*/
|
||||||
|
public void addInterceptors(HandlerInterceptor... interceptors) {
|
||||||
|
register(null, interceptors);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add {@link WebRequestInterceptor}s that should apply to any request.
|
||||||
|
*/
|
||||||
|
public void addInterceptors(WebRequestInterceptor... interceptors) {
|
||||||
|
register(null, asHandlerInterceptorArray(interceptors));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a {@link HandlerInterceptor} with a set of URL path patterns it should apply to.
|
||||||
|
*/
|
||||||
|
public void mapInterceptor(String[] pathPatterns, HandlerInterceptor interceptor) {
|
||||||
|
register(pathPatterns, interceptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a {@link WebRequestInterceptor} with a set of URL path patterns it should apply to.
|
||||||
|
*/
|
||||||
|
public void mapInterceptor(String[] pathPatterns, WebRequestInterceptor interceptors) {
|
||||||
|
register(pathPatterns, asHandlerInterceptorArray(interceptors));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add {@link HandlerInterceptor}s with a set of URL path patterns they should apply to.
|
||||||
|
*/
|
||||||
|
public void mapInterceptors(String[] pathPatterns, HandlerInterceptor... interceptors) {
|
||||||
|
register(pathPatterns, interceptors);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add {@link WebRequestInterceptor}s with a set of URL path patterns they should apply to.
|
||||||
|
*/
|
||||||
|
public void mapInterceptors(String[] pathPatterns, WebRequestInterceptor... interceptors) {
|
||||||
|
register(pathPatterns, asHandlerInterceptorArray(interceptors));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HandlerInterceptor[] asHandlerInterceptorArray(WebRequestInterceptor...interceptors) {
|
||||||
|
HandlerInterceptor[] result = new HandlerInterceptor[interceptors.length];
|
||||||
|
for (int i = 0; i < result.length; i++) {
|
||||||
|
result[i] = new WebRequestHandlerInterceptorAdapter(interceptors[i]);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores the given set of {@link HandlerInterceptor}s and path patterns internally.
|
||||||
|
* @param pathPatterns path patterns or {@code null}
|
||||||
|
* @param interceptors one or more interceptors to be stored
|
||||||
|
*/
|
||||||
|
protected void register(String[] pathPatterns, HandlerInterceptor...interceptors) {
|
||||||
|
Assert.notEmpty(interceptors, "At least one interceptor must be provided");
|
||||||
|
for (HandlerInterceptor interceptor : interceptors) {
|
||||||
|
mappedInterceptors.add(new MappedInterceptor(pathPatterns, interceptor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a {@link MappedInterceptors} instance with all registered interceptors.
|
||||||
|
*/
|
||||||
|
protected MappedInterceptors getMappedInterceptors() {
|
||||||
|
return new MappedInterceptors(mappedInterceptors.toArray(new MappedInterceptor[mappedInterceptors.size()]));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,309 @@
|
||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
import javax.xml.transform.Source;
|
||||||
|
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.BeansException;
|
||||||
|
import org.springframework.beans.factory.BeanInitializationException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.ApplicationContextAware;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.format.support.DefaultFormattingConversionService;
|
||||||
|
import org.springframework.format.support.FormattingConversionService;
|
||||||
|
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.ResourceHttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.xml.XmlAwareFormHttpMessageConverter;
|
||||||
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.validation.Errors;
|
||||||
|
import org.springframework.validation.Validator;
|
||||||
|
import org.springframework.web.HttpRequestHandler;
|
||||||
|
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseStatus;
|
||||||
|
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||||
|
import org.springframework.web.context.ServletContextAware;
|
||||||
|
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||||
|
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||||
|
import org.springframework.web.servlet.DispatcherServlet;
|
||||||
|
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||||
|
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.MappedInterceptors;
|
||||||
|
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||||
|
import org.springframework.web.servlet.mvc.Controller;
|
||||||
|
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||||
|
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
|
||||||
|
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.RequestMappingHandlerMethodAdapter;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodMapping;
|
||||||
|
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* <p>A number of options are available for customizing the default configuration provided by this class.
|
||||||
|
* See {@link EnableMvcConfiguration} and {@link MvcConfigurer} for details.
|
||||||
|
*
|
||||||
|
* <p>Registers these handler mappings:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link RequestMappingHandlerMethodMapping} ordered at 0 for mapping requests to annotated controller methods.
|
||||||
|
* <li>{@link SimpleUrlHandlerMapping} ordered at 1 to map URL paths directly to view names.
|
||||||
|
* <li>{@link BeanNameUrlHandlerMapping} ordered at 2 to map URL paths to controller bean names.
|
||||||
|
* <li>{@link SimpleUrlHandlerMapping} ordered at {@code Integer.MAX_VALUE-1} to serve static resource requests.
|
||||||
|
* <li>{@link SimpleUrlHandlerMapping} ordered at {@code Integer.MAX_VALUE} to forward requests to the default servlet.
|
||||||
|
* </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}.
|
||||||
|
*
|
||||||
|
* <p>Registers these handler adapters:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link RequestMappingHandlerMethodAdapter} for processing requests using annotated controller methods.
|
||||||
|
* <li>{@link HttpRequestHandlerAdapter} for processing requests with {@link HttpRequestHandler}s.
|
||||||
|
* <li>{@link SimpleControllerHandlerAdapter} for processing requests with interface-based {@link Controller}s.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <p>Registers a {@link HandlerExceptionResolverComposite} with this chain of exception resolvers:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link ExceptionHandlerExceptionResolver} for handling exceptions through @{@link ExceptionHandler} methods.
|
||||||
|
* <li>{@link ResponseStatusExceptionResolver} for exceptions annotated with @{@link ResponseStatus}.
|
||||||
|
* <li>{@link DefaultHandlerExceptionResolver} for resolving known Spring exception types
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <p>Registers the following others:
|
||||||
|
* <ul>
|
||||||
|
* <li>{@link FormattingConversionService} for use with annotated controller methods and the spring:eval JSP tag.
|
||||||
|
* <li>{@link Validator} for validating model attributes on annotated controller methods.
|
||||||
|
* <li>{@link MappedInterceptors} containing a list Spring MVC lifecycle interceptors.
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @see EnableMvcConfiguration
|
||||||
|
* @see MvcConfigurer
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
class MvcConfiguration implements ApplicationContextAware, ServletContextAware {
|
||||||
|
|
||||||
|
private final MvcConfigurerComposite configurers = new MvcConfigurerComposite();
|
||||||
|
|
||||||
|
private ServletContext servletContext;
|
||||||
|
|
||||||
|
private ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
@Autowired(required = false)
|
||||||
|
public void setConfigurers(List<MvcConfigurer> configurers) {
|
||||||
|
this.configurers.addConfigurers(configurers);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setServletContext(ServletContext servletContext) {
|
||||||
|
this.servletContext = servletContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
RequestMappingHandlerMethodMapping requestMappingHandlerMapping() {
|
||||||
|
RequestMappingHandlerMethodMapping mapping = new RequestMappingHandlerMethodMapping();
|
||||||
|
mapping.setOrder(0);
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
HandlerMapping viewControllerHandlerMapping() {
|
||||||
|
ViewControllerConfigurer configurer = new ViewControllerConfigurer();
|
||||||
|
configurer.setOrder(1);
|
||||||
|
configurers.addViewControllers(configurer);
|
||||||
|
return configurer.getHandlerMapping();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
BeanNameUrlHandlerMapping beanNameHandlerMapping() {
|
||||||
|
BeanNameUrlHandlerMapping mapping = new BeanNameUrlHandlerMapping();
|
||||||
|
mapping.setOrder(2);
|
||||||
|
return mapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
HandlerMapping resourceHandlerMapping() {
|
||||||
|
ResourceConfigurer configurer = new ResourceConfigurer(applicationContext, servletContext);
|
||||||
|
configurer.setOrder(Integer.MAX_VALUE-1);
|
||||||
|
configurers.configureResourceHandling(configurer);
|
||||||
|
return configurer.getHandlerMapping();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
HandlerMapping defaultServletHandlerMapping() {
|
||||||
|
DefaultServletHandlerConfigurer configurer = new DefaultServletHandlerConfigurer(servletContext);
|
||||||
|
configurers.configureDefaultServletHandling(configurer);
|
||||||
|
return configurer.getHandlerMapping();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
RequestMappingHandlerMethodAdapter requestMappingHandlerAdapter() {
|
||||||
|
RequestMappingHandlerMethodAdapter adapter = new RequestMappingHandlerMethodAdapter();
|
||||||
|
|
||||||
|
ConfigurableWebBindingInitializer bindingInitializer = new ConfigurableWebBindingInitializer();
|
||||||
|
bindingInitializer.setConversionService(conversionService());
|
||||||
|
bindingInitializer.setValidator(validator());
|
||||||
|
adapter.setWebBindingInitializer(bindingInitializer);
|
||||||
|
|
||||||
|
List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<HandlerMethodArgumentResolver>();
|
||||||
|
configurers.addCustomArgumentResolvers(argumentResolvers);
|
||||||
|
adapter.setCustomArgumentResolvers(argumentResolvers);
|
||||||
|
|
||||||
|
List<HandlerMethodReturnValueHandler> returnValueHandlers = new ArrayList<HandlerMethodReturnValueHandler>();
|
||||||
|
configurers.addCustomReturnValueHandlers(returnValueHandlers);
|
||||||
|
adapter.setCustomReturnValueHandlers(returnValueHandlers);
|
||||||
|
|
||||||
|
List<HttpMessageConverter<?>> converters = getDefaultHttpMessageConverters();
|
||||||
|
configurers.configureMessageConverters(converters);
|
||||||
|
adapter.setMessageConverters(converters);
|
||||||
|
|
||||||
|
return adapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name="mvcConversionService")
|
||||||
|
FormattingConversionService conversionService() {
|
||||||
|
FormattingConversionService conversionService = new DefaultFormattingConversionService();
|
||||||
|
configurers.registerFormatters(conversionService);
|
||||||
|
return conversionService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean(name="mvcValidator")
|
||||||
|
Validator validator() {
|
||||||
|
Validator validator = configurers.getValidator();
|
||||||
|
if (validator != null) {
|
||||||
|
return validator;
|
||||||
|
}
|
||||||
|
else if (ClassUtils.isPresent("javax.validation.Validator", getClass().getClassLoader())) {
|
||||||
|
Class<?> clazz;
|
||||||
|
try {
|
||||||
|
String className = "org.springframework.validation.beanvalidation.LocalValidatorFactoryBean";
|
||||||
|
clazz = ClassUtils.forName(className, MvcConfiguration.class.getClassLoader());
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new BeanInitializationException("Could not find default validator");
|
||||||
|
} catch (LinkageError e) {
|
||||||
|
throw new BeanInitializationException("Could not find default validator");
|
||||||
|
}
|
||||||
|
return (Validator) BeanUtils.instantiate(clazz);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new Validator() {
|
||||||
|
public void validate(Object target, Errors errors) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean supports(Class<?> clazz) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<HttpMessageConverter<?>> getDefaultHttpMessageConverters() {
|
||||||
|
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
|
||||||
|
stringConverter.setWriteAcceptCharset(false);
|
||||||
|
|
||||||
|
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
|
||||||
|
converters.add(new ByteArrayHttpMessageConverter());
|
||||||
|
converters.add(stringConverter);
|
||||||
|
converters.add(new ResourceHttpMessageConverter());
|
||||||
|
converters.add(new SourceHttpMessageConverter<Source>());
|
||||||
|
converters.add(new XmlAwareFormHttpMessageConverter());
|
||||||
|
|
||||||
|
ClassLoader classLoader = getClass().getClassLoader();
|
||||||
|
if (ClassUtils.isPresent("javax.xml.bind.Binder", classLoader)) {
|
||||||
|
converters.add(new Jaxb2RootElementHttpMessageConverter());
|
||||||
|
}
|
||||||
|
if (ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper", classLoader)) {
|
||||||
|
converters.add(new MappingJacksonHttpMessageConverter());
|
||||||
|
}
|
||||||
|
if (ClassUtils.isPresent("com.sun.syndication.feed.WireFeed", classLoader)) {
|
||||||
|
converters.add(new AtomFeedHttpMessageConverter());
|
||||||
|
converters.add(new RssChannelHttpMessageConverter());
|
||||||
|
}
|
||||||
|
|
||||||
|
return converters;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
HttpRequestHandlerAdapter httpRequestHandlerAdapter() {
|
||||||
|
return new HttpRequestHandlerAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
SimpleControllerHandlerAdapter simpleControllerHandlerAdapter() {
|
||||||
|
return new SimpleControllerHandlerAdapter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
HandlerExceptionResolver handlerExceptionResolver() throws Exception {
|
||||||
|
List<HandlerExceptionResolver> resolvers = new ArrayList<HandlerExceptionResolver>();
|
||||||
|
resolvers.add(createExceptionHandlerExceptionResolver());
|
||||||
|
resolvers.add(new ResponseStatusExceptionResolver());
|
||||||
|
resolvers.add(new DefaultHandlerExceptionResolver());
|
||||||
|
configurers.configureHandlerExceptionResolvers(resolvers);
|
||||||
|
|
||||||
|
HandlerExceptionResolverComposite composite = new HandlerExceptionResolverComposite();
|
||||||
|
composite.setOrder(0);
|
||||||
|
composite.setExceptionResolvers(resolvers);
|
||||||
|
return composite;
|
||||||
|
}
|
||||||
|
|
||||||
|
private HandlerExceptionResolver createExceptionHandlerExceptionResolver() throws Exception {
|
||||||
|
ExceptionHandlerExceptionResolver resolver = new ExceptionHandlerExceptionResolver();
|
||||||
|
|
||||||
|
List<HttpMessageConverter<?>> converters = getDefaultHttpMessageConverters();
|
||||||
|
configurers.configureMessageConverters(converters);
|
||||||
|
resolver.setMessageConverters(converters);
|
||||||
|
resolver.setOrder(0);
|
||||||
|
|
||||||
|
resolver.afterPropertiesSet();
|
||||||
|
return resolver;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
MappedInterceptors mappedInterceptors() {
|
||||||
|
InterceptorConfigurer configurer = new InterceptorConfigurer();
|
||||||
|
configurer.addInterceptor(new ConversionServiceExposingInterceptor(conversionService()));
|
||||||
|
configurers.addInterceptors(configurer);
|
||||||
|
return configurer.getMappedInterceptors();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.convert.converter.Converter;
|
||||||
|
import org.springframework.format.Formatter;
|
||||||
|
import org.springframework.format.FormatterRegistry;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
|
import org.springframework.validation.Validator;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||||
|
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||||
|
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||||
|
import org.springframework.web.servlet.DispatcherServlet;
|
||||||
|
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||||
|
import org.springframework.web.servlet.HandlerInterceptor;
|
||||||
|
|
||||||
|
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}
|
||||||
|
* 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}.
|
||||||
|
*
|
||||||
|
* <p>Implementations of this interface will find it convenient to extend {@link MvcConfigurerSupport} that
|
||||||
|
* provides default method implementations and allows overriding only methods of interest.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @author Keith Donald
|
||||||
|
* @author David Syer
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public interface MvcConfigurer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register application-specific {@link Converter}s and {@link Formatter}s for use in Spring MVC.
|
||||||
|
*/
|
||||||
|
void registerFormatters(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
|
||||||
|
*/
|
||||||
|
void configureMessageConverters(List<HttpMessageConverter<?>> converters);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provide a custom {@link Validator} type replacing the one that would be created by default otherwise. If this
|
||||||
|
* method returns {@code null}, and assuming a JSR-303 implementation is available on the classpath, a validator
|
||||||
|
* of type {@link org.springframework.validation.beanvalidation.LocalValidatorFactoryBean} is created by default.
|
||||||
|
*/
|
||||||
|
Validator getValidator();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add custom {@link HandlerMethodArgumentResolver}s to use for resolving argument values
|
||||||
|
* on @{@link RequestMapping} and @{@link ExceptionHandler} methods.
|
||||||
|
* @param argumentResolvers the list of custom converters, initially empty
|
||||||
|
*/
|
||||||
|
void addCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add custom {@link HandlerMethodReturnValueHandler}s to use for handling return values
|
||||||
|
* from @{@link RequestMapping} and @{@link ExceptionHandler} methods.
|
||||||
|
* @param returnValueHandlers the list of custom handlers, initially empty
|
||||||
|
*/
|
||||||
|
void addCustomReturnValueHandlers(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
|
||||||
|
*/
|
||||||
|
void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add Spring MVC interceptors. 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);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map URL paths to view names. This is convenient when a request can be rendered without a controller.
|
||||||
|
*/
|
||||||
|
void addViewControllers(ViewControllerConfigurer viewControllerConfigurer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure a handler for serving static resources such as images, js, and, css files through Spring MVC
|
||||||
|
* including setting cache headers optimized for efficient loading in a web browser. Resources can be served
|
||||||
|
* out of locations under web application root, from the classpath, and others.
|
||||||
|
*/
|
||||||
|
void configureResourceHandling(ResourceConfigurer resourceConfigurer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure a handler for delegating unhandled requests by forwarding to the Servlet container's default
|
||||||
|
* servlet. This is commonly used when the {@link DispatcherServlet} is mapped to "/", which results in
|
||||||
|
* cleaner URLs (without a servlet prefix) but may need to still allow some requests (e.g. static resources)
|
||||||
|
* to be handled by the Servlet container's default servlet.
|
||||||
|
*/
|
||||||
|
void configureDefaultServletHandling(DefaultServletHandlerConfigurer handlerConfigurer);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
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 {@link MvcConfigurer} implementation that delegates to other {@link MvcConfigurer} instances.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
class MvcConfigurerComposite implements MvcConfigurer {
|
||||||
|
|
||||||
|
private final List<MvcConfigurer> configurers = new ArrayList<MvcConfigurer>();
|
||||||
|
|
||||||
|
void addConfigurers(List<MvcConfigurer> configurers) {
|
||||||
|
if (configurers != null) {
|
||||||
|
this.configurers.addAll(configurers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerFormatters(FormatterRegistry formatterRegistry) {
|
||||||
|
for (MvcConfigurer configurer : configurers) {
|
||||||
|
configurer.registerFormatters(formatterRegistry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
|
for (MvcConfigurer configurer : configurers) {
|
||||||
|
configurer.configureMessageConverters(converters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||||
|
for (MvcConfigurer configurer : configurers) {
|
||||||
|
configurer.addCustomArgumentResolvers(argumentResolvers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addCustomReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
||||||
|
for (MvcConfigurer configurer : configurers) {
|
||||||
|
configurer.addCustomReturnValueHandlers(returnValueHandlers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||||
|
for (MvcConfigurer configurer : configurers) {
|
||||||
|
configurer.configureHandlerExceptionResolvers(exceptionResolvers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addInterceptors(InterceptorConfigurer interceptorRegistry) {
|
||||||
|
for (MvcConfigurer configurer : configurers) {
|
||||||
|
configurer.addInterceptors(interceptorRegistry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addViewControllers(ViewControllerConfigurer viewControllerConfigurer) {
|
||||||
|
for (MvcConfigurer configurer : configurers) {
|
||||||
|
configurer.addViewControllers(viewControllerConfigurer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configureResourceHandling(ResourceConfigurer resourceConfigurer) {
|
||||||
|
for (MvcConfigurer configurer : configurers) {
|
||||||
|
configurer.configureResourceHandling(resourceConfigurer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer handlerConfigurer) {
|
||||||
|
for (MvcConfigurer configurer : configurers) {
|
||||||
|
configurer.configureDefaultServletHandling(handlerConfigurer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Validator getValidator() {
|
||||||
|
Map<MvcConfigurer, Validator> validators = new HashMap<MvcConfigurer, Validator>();
|
||||||
|
for (MvcConfigurer configurer : configurers) {
|
||||||
|
Validator validator = configurer.getValidator();
|
||||||
|
if (validator != null) {
|
||||||
|
validators.put(configurer, validator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (validators.size() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
else if (validators.size() == 1) {
|
||||||
|
return validators.values().iterator().next();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalStateException(
|
||||||
|
"Multiple custom validators provided from [" + validators.keySet() + "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
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.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.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public abstract class MvcConfigurerSupport implements MvcConfigurer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>This implementation is empty.
|
||||||
|
*/
|
||||||
|
public void registerFormatters(FormatterRegistry formatterRegistry) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>This implementation is empty.
|
||||||
|
*/
|
||||||
|
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>This implementation is empty.
|
||||||
|
*/
|
||||||
|
public void configureValidator(Validator validator) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>This implementation returns {@code null}
|
||||||
|
*/
|
||||||
|
public Validator getValidator() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>This implementation is empty.
|
||||||
|
*/
|
||||||
|
public void addCustomArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>This implementation is empty.
|
||||||
|
*/
|
||||||
|
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>This implementation is empty.
|
||||||
|
*/
|
||||||
|
public void addInterceptors(InterceptorConfigurer interceptorConfigurer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>This implementation is empty.
|
||||||
|
*/
|
||||||
|
public void addViewControllers(ViewControllerConfigurer viewControllerConfigurer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>This implementation is empty.
|
||||||
|
*/
|
||||||
|
public void configureResourceHandling(ResourceConfigurer resourceConfigurer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>This implementation is empty.
|
||||||
|
*/
|
||||||
|
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer handlerConfigurer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,197 @@
|
||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.servlet.ServletContext;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
import org.springframework.util.CollectionUtils;
|
||||||
|
import org.springframework.web.HttpRequestHandler;
|
||||||
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||||
|
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps with configuring a handler for serving static resources such as images, css files and others through
|
||||||
|
* Spring MVC including setting cache headers optimized for efficient loading in a web browser. Resources can
|
||||||
|
* be served out of locations under web application root, from the classpath, and others.
|
||||||
|
*
|
||||||
|
* <p>To configure resource handling, use {@link #addPathMappings(String...)} to add one or more URL path patterns
|
||||||
|
* within the current Servlet context, to use for serving resources from the handler, such as {@code "/resources/**"}.
|
||||||
|
*
|
||||||
|
* <p>Then use {@link #addResourceLocations(String...)} to add one or more locations from which to serve
|
||||||
|
* static content. For example, {{@code "/"}, {@code "classpath:/META-INF/public-web-resources/"}} allows resources
|
||||||
|
* to be served both from the web application root and from any JAR on the classpath that contains a
|
||||||
|
* {@code /META-INF/public-web-resources/} directory, with resources in the web application root taking precedence.
|
||||||
|
*
|
||||||
|
* <p>Optionally use {@link #setCachePeriod(Integer)} to specify the cache period for the resources served by the
|
||||||
|
* handler and {@link #setOrder(int)} to set the order in which to serve requests relative to other
|
||||||
|
* {@link HandlerMapping} instances in the Spring MVC web application context.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*
|
||||||
|
* @see DefaultServletHandlerConfigurer
|
||||||
|
*/
|
||||||
|
public class ResourceConfigurer {
|
||||||
|
|
||||||
|
private final List<String> pathPatterns = new ArrayList<String>();
|
||||||
|
|
||||||
|
private final List<Resource> locations = new ArrayList<Resource>();
|
||||||
|
|
||||||
|
private Integer cachePeriod;
|
||||||
|
|
||||||
|
private int order = Integer.MAX_VALUE -1;
|
||||||
|
|
||||||
|
private final ServletContext servletContext;
|
||||||
|
|
||||||
|
private final ApplicationContext applicationContext;
|
||||||
|
|
||||||
|
public ResourceConfigurer(ApplicationContext applicationContext, ServletContext servletContext) {
|
||||||
|
Assert.notNull(applicationContext, "ApplicationContext is required");
|
||||||
|
this.applicationContext = applicationContext;
|
||||||
|
this.servletContext = servletContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a URL path pattern within the current Servlet context to use for serving static resources
|
||||||
|
* using the Spring MVC {@link ResourceHttpRequestHandler}, for example {@code "/resources/**"}.
|
||||||
|
* @return the same {@link ResourceConfigurer} instance for chained method invocation
|
||||||
|
*/
|
||||||
|
public ResourceConfigurer addPathMapping(String pathPattern) {
|
||||||
|
return addPathMappings(pathPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add several URL path patterns within the current Servlet context to use for serving static resources
|
||||||
|
* using the Spring MVC {@link ResourceHttpRequestHandler}, for example {@code "/resources/**"}.
|
||||||
|
* @return the same {@link ResourceConfigurer} instance for chained method invocation
|
||||||
|
*/
|
||||||
|
public ResourceConfigurer addPathMappings(String...pathPatterns) {
|
||||||
|
for (String path : pathPatterns) {
|
||||||
|
this.pathPatterns.add(path);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add resource location from which to serve static content. The location must point to a valid
|
||||||
|
* directory. <p>For example, a value of {@code "/"} will allow resources to be served both from the web
|
||||||
|
* application root. Also see {@link #addResourceLocations(String...)} for mapping several resource locations.
|
||||||
|
* @return the same {@link ResourceConfigurer} instance for chained method invocation
|
||||||
|
*/
|
||||||
|
public ResourceConfigurer addResourceLocation(String resourceLocation) {
|
||||||
|
return addResourceLocations(resourceLocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add one or more resource locations from which to serve static content. Each location must point to a valid
|
||||||
|
* directory. Multiple locations may be specified as a comma-separated list, and the locations will be checked
|
||||||
|
* for a given resource in the order specified.
|
||||||
|
* <p>For example, {{@code "/"}, {@code "classpath:/META-INF/public-web-resources/"}} allows resources to
|
||||||
|
* be served both from the web application root and from any JAR on the classpath that contains a
|
||||||
|
* {@code /META-INF/public-web-resources/} directory, with resources in the web application root taking precedence.
|
||||||
|
* @return the same {@link ResourceConfigurer} instance for chained method invocation
|
||||||
|
*/
|
||||||
|
public ResourceConfigurer addResourceLocations(String...resourceLocations) {
|
||||||
|
for (String location : resourceLocations) {
|
||||||
|
this.locations.add(applicationContext.getResource(location));
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the cache period for the resources served by the resource handler, in seconds. The default is to not
|
||||||
|
* send any cache headers but to rely on last-modified timestamps only. Set to 0 in order to send cache headers
|
||||||
|
* that prevent caching, or to a positive number of seconds to send cache headers with the given max-age value.
|
||||||
|
* @param cachePeriod the time to cache resources in seconds
|
||||||
|
* @return the same {@link ResourceConfigurer} instance for chained method invocation
|
||||||
|
*/
|
||||||
|
public ResourceConfigurer setCachePeriod(Integer cachePeriod) {
|
||||||
|
this.cachePeriod = cachePeriod;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the cache period for static resources served by the resource handler.
|
||||||
|
*/
|
||||||
|
public Integer getCachePeriod() {
|
||||||
|
return cachePeriod;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the order in which to serve static resources relative to other {@link HandlerMapping} instances in the
|
||||||
|
* Spring MVC web application context. The default value is {@code Integer.MAX_VALUE-1}.
|
||||||
|
*/
|
||||||
|
public ResourceConfigurer setOrder(int order) {
|
||||||
|
this.order = order;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the order in which to serve static resources relative other {@link HandlerMapping} instances.
|
||||||
|
* @return the same {@link ResourceConfigurer} instance for chained method invocation
|
||||||
|
*/
|
||||||
|
public Integer getOrder() {
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a {@link SimpleUrlHandlerMapping} with a {@link ResourceHttpRequestHandler} mapped to one or more
|
||||||
|
* URL path patterns. If the no path patterns were specified, the HandlerMapping returned contains an empty map.
|
||||||
|
*/
|
||||||
|
protected SimpleUrlHandlerMapping getHandlerMapping() {
|
||||||
|
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
|
||||||
|
handlerMapping.setOrder(order);
|
||||||
|
handlerMapping.setUrlMap(getUrlMap());
|
||||||
|
return handlerMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, HttpRequestHandler> getUrlMap() {
|
||||||
|
Map<String, HttpRequestHandler> urlMap = new LinkedHashMap<String, HttpRequestHandler>();
|
||||||
|
if (!pathPatterns.isEmpty()) {
|
||||||
|
ResourceHttpRequestHandler requestHandler = createRequestHandler();
|
||||||
|
for (String pathPattern : pathPatterns) {
|
||||||
|
urlMap.put(pathPattern, requestHandler);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return urlMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a {@link ResourceHttpRequestHandler} instance.
|
||||||
|
*/
|
||||||
|
protected ResourceHttpRequestHandler createRequestHandler() {
|
||||||
|
Assert.isTrue(!CollectionUtils.isEmpty(locations), "Path patterns specified but not resource locations.");
|
||||||
|
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
|
||||||
|
requestHandler.setApplicationContext(applicationContext);
|
||||||
|
requestHandler.setServletContext(servletContext);
|
||||||
|
requestHandler.setLocations(locations);
|
||||||
|
if (cachePeriod != null) {
|
||||||
|
requestHandler.setCacheSeconds(cachePeriod);
|
||||||
|
}
|
||||||
|
return requestHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
import org.springframework.web.servlet.RequestToViewNameTranslator;
|
||||||
|
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||||
|
import org.springframework.web.servlet.mvc.Controller;
|
||||||
|
import org.springframework.web.servlet.mvc.ParameterizableViewController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps with view controllers. View controllers provide a direct mapping between a URL path and view name. This is
|
||||||
|
* useful when serving requests that don't require application-specific controller logic and can be forwarded
|
||||||
|
* directly to a view for rendering.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class ViewControllerConfigurer {
|
||||||
|
|
||||||
|
private final Map<String, Controller> urlMap = new LinkedHashMap<String, Controller>();
|
||||||
|
|
||||||
|
private int order = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the URL path to a view name derived by convention through the DispatcherServlet's
|
||||||
|
* {@link RequestToViewNameTranslator}.
|
||||||
|
* @return the same {@link ViewControllerConfigurer} instance for convenient chained method invocation
|
||||||
|
*/
|
||||||
|
public ViewControllerConfigurer mapViewNameByConvention(String urlPath) {
|
||||||
|
return mapViewName(urlPath, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map the URL path to the specified view name.
|
||||||
|
* @return the same {@link ViewControllerConfigurer} instance for convenient chained method invocation
|
||||||
|
*/
|
||||||
|
public ViewControllerConfigurer mapViewName(String urlPath, String viewName) {
|
||||||
|
ParameterizableViewController controller = new ParameterizableViewController();
|
||||||
|
controller.setViewName(viewName);
|
||||||
|
urlMap.put(urlPath, controller);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specify the order in which to check view controller path mappings relative to other {@link HandlerMapping}
|
||||||
|
* instances in the Spring MVC web application context. The default value is 1.
|
||||||
|
*/
|
||||||
|
public void setOrder(int order) {
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the order in which to check view controller path mappings relative to other {@link HandlerMapping}s.
|
||||||
|
*/
|
||||||
|
public int getOrder() {
|
||||||
|
return order;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a {@link SimpleUrlHandlerMapping} with URL path to view controllers mappings.
|
||||||
|
*/
|
||||||
|
protected SimpleUrlHandlerMapping getHandlerMapping() {
|
||||||
|
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
|
||||||
|
handlerMapping.setOrder(order);
|
||||||
|
handlerMapping.setUrlMap(urlMap);
|
||||||
|
return handlerMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,51 @@
|
||||||
|
package org.springframework.web.servlet.handler;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||||
|
import org.springframework.web.servlet.ModelAndView;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link HandlerExceptionResolver} that delegates to a list of {@link HandlerExceptionResolver}s.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 3.1
|
||||||
|
*/
|
||||||
|
public class HandlerExceptionResolverComposite implements HandlerExceptionResolver, Ordered {
|
||||||
|
|
||||||
|
private List<HandlerExceptionResolver> resolvers;
|
||||||
|
|
||||||
|
private int order = Ordered.LOWEST_PRECEDENCE;
|
||||||
|
|
||||||
|
public void setOrder(int order) {
|
||||||
|
this.order = order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getOrder() {
|
||||||
|
return this.order;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||||
|
this.resolvers = exceptionResolvers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ModelAndView resolveException(HttpServletRequest request,
|
||||||
|
HttpServletResponse response,
|
||||||
|
Object handler,
|
||||||
|
Exception ex) {
|
||||||
|
if (resolvers != null) {
|
||||||
|
for (HandlerExceptionResolver handlerExceptionResolver : resolvers) {
|
||||||
|
ModelAndView mav = handlerExceptionResolver.resolveException(request, response, handler, ex);
|
||||||
|
if (mav != null) {
|
||||||
|
return mav;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -30,8 +30,10 @@ import org.springframework.web.method.support.InvocableHandlerMethod;
|
||||||
import org.springframework.web.servlet.HandlerMapping;
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link InitBinderMethodDataBinderFactory} that creates a {@link ServletRequestDataBinder}.
|
* An {@link InitBinderMethodDataBinderFactory} variation instantiating a data binder of type
|
||||||
*
|
* {@link ServletRequestDataBinder} and further extending it with the ability to add URI template variables
|
||||||
|
* to the values used in data binding.
|
||||||
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
|
|
@ -39,7 +41,7 @@ public class ServletInitBinderMethodDataBinderFactory extends InitBinderMethodDa
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an {@link ServletInitBinderMethodDataBinderFactory} instance.
|
* Create an {@link ServletInitBinderMethodDataBinderFactory} instance.
|
||||||
* @param initBinderMethods init binder methods to use to initialize new data binders.
|
* @param initBinderMethods init binder methods to use to initialize new data binders.
|
||||||
* @param bindingInitializer a WebBindingInitializer to use to initialize created data binder instances.
|
* @param bindingInitializer a WebBindingInitializer to use to initialize created data binder instances.
|
||||||
*/
|
*/
|
||||||
public ServletInitBinderMethodDataBinderFactory(List<InvocableHandlerMethod> initBinderMethods,
|
public ServletInitBinderMethodDataBinderFactory(List<InvocableHandlerMethod> initBinderMethods,
|
||||||
|
|
@ -48,34 +50,44 @@ public class ServletInitBinderMethodDataBinderFactory extends InitBinderMethodDa
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a Servlet data binder.
|
* {@inheritDoc}
|
||||||
|
* <p>This method creates a {@link ServletRequestDataBinder} instance that also adds URI template variables to
|
||||||
|
* the values used in data binding.
|
||||||
|
* <p>Subclasses wishing to override this method to provide their own ServletRequestDataBinder type can use the
|
||||||
|
* {@link #addUriTemplateVariables(MutablePropertyValues)} method to include URI template variables as follows:
|
||||||
|
* <pre>
|
||||||
|
* return new CustomServletRequestDataBinder(target, objectName) {
|
||||||
|
* protected void doBind(MutablePropertyValues mpvs) {
|
||||||
|
* addUriTemplateVariables(mpvs);
|
||||||
|
* super.doBind(mpvs);
|
||||||
|
* }
|
||||||
|
* };
|
||||||
|
* </pre>
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected WebDataBinder createBinderInstance(Object target, String objectName) {
|
protected WebDataBinder createBinderInstance(Object target, String objectName) {
|
||||||
return new ServletRequestPathVarDataBinder(target, objectName);
|
return new ServletRequestDataBinder(target, objectName) {
|
||||||
|
|
||||||
|
protected void doBind(MutablePropertyValues mpvs) {
|
||||||
|
addUriTemplateVariables(mpvs);
|
||||||
|
super.doBind(mpvs);
|
||||||
|
}
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds URI template variables to the map of request values used to do data binding.
|
* Adds URI template variables to the given property values.
|
||||||
|
* @param mpvs the PropertyValues to add URI template variables to
|
||||||
*/
|
*/
|
||||||
private static class ServletRequestPathVarDataBinder extends ServletRequestDataBinder {
|
@SuppressWarnings("unchecked")
|
||||||
|
protected void addUriTemplateVariables(MutablePropertyValues mpvs) {
|
||||||
public ServletRequestPathVarDataBinder(Object target, String objectName) {
|
RequestAttributes requestAttrs = RequestContextHolder.getRequestAttributes();
|
||||||
super(target, objectName);
|
if (requestAttrs != null) {
|
||||||
}
|
String key = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
|
||||||
|
int scope = RequestAttributes.SCOPE_REQUEST;
|
||||||
@SuppressWarnings("unchecked")
|
Map<String, String> uriTemplateVars = (Map<String, String>) requestAttrs.getAttribute(key, scope);
|
||||||
@Override
|
mpvs.addPropertyValues(uriTemplateVars);
|
||||||
protected void doBind(MutablePropertyValues mpvs) {
|
|
||||||
RequestAttributes requestAttrs = RequestContextHolder.getRequestAttributes();
|
|
||||||
if (requestAttrs != null) {
|
|
||||||
String key = HandlerMapping.URI_TEMPLATE_VARIABLES_ATTRIBUTE;
|
|
||||||
int scope = RequestAttributes.SCOPE_REQUEST;
|
|
||||||
Map<String, String> uriTemplateVars = (Map<String, String>) requestAttrs.getAttribute(key, scope);
|
|
||||||
mpvs.addPropertyValues(uriTemplateVars);
|
|
||||||
}
|
|
||||||
super.doBind(mpvs);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -30,16 +30,15 @@ import org.springframework.web.method.support.HandlerMethodReturnValueHandlerCom
|
||||||
import org.springframework.web.method.support.InvocableHandlerMethod;
|
import org.springframework.web.method.support.InvocableHandlerMethod;
|
||||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
import org.springframework.web.servlet.View;
|
import org.springframework.web.servlet.View;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.support.ServletResponseMethodArgumentResolver;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extends {@link InvocableHandlerMethod} with the ability to handle the value returned from the method through
|
* Extends {@link InvocableHandlerMethod} with the ability to handle the value returned from the method through
|
||||||
* a registered {@link HandlerMethodArgumentResolver} that supports the given return value type.
|
* a registered {@link HandlerMethodArgumentResolver} that supports the given return value type.
|
||||||
* Return value handling may include writing to the response or updating the {@link ModelAndViewContainer} structure.
|
* Return value handling may include writing to the response or updating the {@link ModelAndViewContainer} structure.
|
||||||
*
|
*
|
||||||
* <p>If the underlying method has a {@link ResponseStatus} instruction, the status on the response is set
|
* <p>If the underlying method has a {@link ResponseStatus} instruction, the status on the response is set
|
||||||
* accordingly after the method is invoked but before the return value is handled.
|
* accordingly after the method is invoked but before the return value is handled.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
* @see #invokeAndHandle(NativeWebRequest, ModelAndViewContainer, Object...)
|
* @see #invokeAndHandle(NativeWebRequest, ModelAndViewContainer, Object...)
|
||||||
|
|
@ -47,9 +46,9 @@ import org.springframework.web.servlet.mvc.method.annotation.support.ServletResp
|
||||||
public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||||
|
|
||||||
private HttpStatus responseStatus;
|
private HttpStatus responseStatus;
|
||||||
|
|
||||||
private String responseReason;
|
private String responseReason;
|
||||||
|
|
||||||
private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
|
private HandlerMethodReturnValueHandlerComposite returnValueHandlers;
|
||||||
|
|
||||||
public void setHandlerMethodReturnValueHandlers(HandlerMethodReturnValueHandlerComposite returnValueHandlers) {
|
public void setHandlerMethodReturnValueHandlers(HandlerMethodReturnValueHandlerComposite returnValueHandlers) {
|
||||||
|
|
@ -72,26 +71,26 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes the method and handles the return value through a registered {@link HandlerMethodReturnValueHandler}.
|
* Invokes the method and handles the return value through a registered {@link HandlerMethodReturnValueHandler}.
|
||||||
* <p>Return value handling may be skipped entirely when the method returns {@code null} (also possibly due
|
* <p>Return value handling may be skipped entirely when the method returns {@code null} (also possibly due
|
||||||
* to a {@code void} return type) and one of the following additional conditions is true:
|
* to a {@code void} return type) and one of the following additional conditions is true:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>A {@link HandlerMethodArgumentResolver} has set the {@link ModelAndViewContainer#setResolveView(boolean)}
|
* <li>A {@link HandlerMethodArgumentResolver} has set the {@link ModelAndViewContainer#setResolveView(boolean)}
|
||||||
* flag to {@code false} -- e.g. method arguments providing access to the response.
|
* flag to {@code false} -- e.g. method arguments providing access to the response.
|
||||||
* <li>The request qualifies as "not modified" as defined in {@link ServletWebRequest#checkNotModified(long)}
|
* <li>The request qualifies as "not modified" as defined in {@link ServletWebRequest#checkNotModified(long)}
|
||||||
* and {@link ServletWebRequest#checkNotModified(String)}. In this case a response with "not modified" response
|
* and {@link ServletWebRequest#checkNotModified(String)}. In this case a response with "not modified" response
|
||||||
* headers will be automatically generated without the need for return value handling.
|
* headers will be automatically generated without the need for return value handling.
|
||||||
* <li>The status on the response is set due to a @{@link ResponseStatus} instruction.
|
* <li>The status on the response is set due to a @{@link ResponseStatus} instruction.
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p>After the return value is handled, callers of this method can use the {@link ModelAndViewContainer}
|
* <p>After the return value is handled, callers of this method can use the {@link ModelAndViewContainer}
|
||||||
* to gain access to model attributes, view selection choices, and to check if view resolution is even needed.
|
* to gain access to model attributes, view selection choices, and to check if view resolution is even needed.
|
||||||
*
|
*
|
||||||
* @param request the current request
|
* @param request the current request
|
||||||
* @param mavContainer the {@link ModelAndViewContainer} for the current request
|
* @param mavContainer the {@link ModelAndViewContainer} for the current request
|
||||||
* @param providedArgs argument values to try to use without the need for view resolution
|
* @param providedArgs argument values to try to use without the need for view resolution
|
||||||
*/
|
*/
|
||||||
public final void invokeAndHandle(NativeWebRequest request,
|
public final void invokeAndHandle(NativeWebRequest request,
|
||||||
ModelAndViewContainer mavContainer,
|
ModelAndViewContainer mavContainer,
|
||||||
Object...providedArgs) throws Exception {
|
Object...providedArgs) throws Exception {
|
||||||
|
|
||||||
if (!returnValueHandlers.supportsReturnType(getReturnType())) {
|
if (!returnValueHandlers.supportsReturnType(getReturnType())) {
|
||||||
|
|
@ -108,7 +107,7 @@ public class ServletInvocableHandlerMethod extends InvocableHandlerMethod {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mavContainer.setResolveView(true);
|
mavContainer.setResolveView(true);
|
||||||
|
|
||||||
returnValueHandlers.handleReturnValue(returnValue, getReturnType(), mavContainer, request);
|
returnValueHandlers.handleReturnValue(returnValue, getReturnType(), mavContainer, request);
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,9 @@ import org.springframework.web.context.request.NativeWebRequest;
|
||||||
import org.springframework.web.method.annotation.support.ModelAttributeMethodProcessor;
|
import org.springframework.web.method.annotation.support.ModelAttributeMethodProcessor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Servlet-specific {@link ModelAttributeMethodProcessor} variant that casts the {@link WebDataBinder}
|
* A Servlet-specific {@link ModelAttributeMethodProcessor} variant that casts the {@link WebDataBinder}
|
||||||
* instance to {@link ServletRequestDataBinder} prior to invoking data binding.
|
* instance to {@link ServletRequestDataBinder} prior to invoking data binding.
|
||||||
*
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
|
|
@ -36,7 +36,7 @@ public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodPr
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param useDefaultResolution in default resolution mode a method argument that isn't a simple type, as
|
* @param useDefaultResolution in default resolution mode a method argument that isn't a simple type, as
|
||||||
* defined in {@link BeanUtils#isSimpleProperty(Class)}, is treated as a model attribute even if it doesn't
|
* defined in {@link BeanUtils#isSimpleProperty(Class)}, is treated as a model attribute even if it doesn't
|
||||||
* have an @{@link ModelAttribute} annotation with its name derived from the model attribute type.
|
* have an @{@link ModelAttribute} annotation with its name derived from the model attribute type.
|
||||||
*/
|
*/
|
||||||
public ServletModelAttributeMethodProcessor(boolean useDefaultResolution) {
|
public ServletModelAttributeMethodProcessor(boolean useDefaultResolution) {
|
||||||
|
|
@ -44,12 +44,15 @@ public class ServletModelAttributeMethodProcessor extends ModelAttributeMethodPr
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expects the data binder to be an instance of {@link ServletRequestDataBinder}.
|
* {@inheritDoc}
|
||||||
|
* <p>This method downcasts the binder instance to {@link ServletRequestDataBinder} and invokes
|
||||||
|
* its bind method passing a {@link ServletRequest} to it.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void doBind(WebDataBinder binder, NativeWebRequest request) {
|
protected void doBind(WebDataBinder binder, NativeWebRequest request) {
|
||||||
ServletRequest servletRequest = request.getNativeRequest(ServletRequest.class);
|
ServletRequest servletRequest = request.getNativeRequest(ServletRequest.class);
|
||||||
((ServletRequestDataBinder) binder).bind(servletRequest);
|
ServletRequestDataBinder servletBinder = (ServletRequestDataBinder) binder;
|
||||||
|
servletBinder.bind(servletRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
@ -17,31 +17,39 @@
|
||||||
package org.springframework.web.servlet.mvc.method.annotation.support;
|
package org.springframework.web.servlet.mvc.method.annotation.support;
|
||||||
|
|
||||||
import org.springframework.core.MethodParameter;
|
import org.springframework.core.MethodParameter;
|
||||||
|
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
import org.springframework.web.context.request.NativeWebRequest;
|
import org.springframework.web.context.request.NativeWebRequest;
|
||||||
import org.springframework.web.method.annotation.support.ModelAttributeMethodProcessor;
|
|
||||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||||
import org.springframework.web.method.support.ModelAndViewContainer;
|
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
|
import org.springframework.web.servlet.RequestToViewNameTranslator;
|
||||||
import org.springframework.web.servlet.View;
|
import org.springframework.web.servlet.View;
|
||||||
|
import org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles return values that are of type {@link View} or {@link String} (i.e. a logical view name).
|
* Handles return values that are of type {@code void}, {@code String} (i.e. logical view name), or {@link View}.
|
||||||
* <p>Since a {@link String} return value may handled in different ways, especially in combination with method
|
*
|
||||||
* annotations, this handler should be registered after return value handlers that look for method annotations
|
* <p>A {@code null} return value, either due to a void return type or as the actual value returned from a
|
||||||
* such as the {@link ModelAttributeMethodProcessor} and the {@link RequestResponseBodyMethodProcessor}.
|
* method is left unhandled, leaving it to the configured {@link RequestToViewNameTranslator} to resolve the
|
||||||
*
|
* request to an actual view name. By default it is the {@link DefaultRequestToViewNameTranslator}.
|
||||||
|
*
|
||||||
|
* <p>Since a {@link String} return value may handled in different ways, especially in combination with method
|
||||||
|
* annotations such as @{@link ModelAttribute} and @{@link ResponseBody}, this handler should be ordered after
|
||||||
|
* return value handlers that support method annotations.
|
||||||
|
*
|
||||||
* @author Rossen Stoyanchev
|
* @author Rossen Stoyanchev
|
||||||
* @since 3.1
|
* @since 3.1
|
||||||
*/
|
*/
|
||||||
public class ViewMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
|
public class ViewMethodReturnValueHandler implements HandlerMethodReturnValueHandler {
|
||||||
|
|
||||||
public boolean supportsReturnType(MethodParameter returnType) {
|
public boolean supportsReturnType(MethodParameter returnType) {
|
||||||
Class<?> paramType = returnType.getParameterType();
|
Class<?> type = returnType.getParameterType();
|
||||||
return (View.class.isAssignableFrom(paramType) || (String.class.equals(paramType)));
|
return (void.class.equals(type) || String.class.equals(type) || View.class.isAssignableFrom(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleReturnValue(Object returnValue,
|
public void handleReturnValue(Object returnValue,
|
||||||
MethodParameter returnType,
|
MethodParameter returnType,
|
||||||
ModelAndViewContainer mavContainer,
|
ModelAndViewContainer mavContainer,
|
||||||
NativeWebRequest webRequest) throws Exception {
|
NativeWebRequest webRequest) throws Exception {
|
||||||
if (returnValue == null) {
|
if (returnValue == null) {
|
||||||
return;
|
return;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import javax.servlet.RequestDispatcher;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
import org.springframework.mock.web.MockRequestDispatcher;
|
||||||
|
import org.springframework.mock.web.MockServletContext;
|
||||||
|
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||||
|
import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test fixture with a {@link DefaultServletHandlerConfigurer}.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
*/
|
||||||
|
public class DefaultServletHandlerConfigurerTests {
|
||||||
|
|
||||||
|
private DefaultServletHandlerConfigurer configurer;
|
||||||
|
|
||||||
|
private DispatchingMockServletContext servletContext;
|
||||||
|
|
||||||
|
private MockHttpServletResponse response;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
response = new MockHttpServletResponse();
|
||||||
|
servletContext = new DispatchingMockServletContext();
|
||||||
|
configurer = new DefaultServletHandlerConfigurer(servletContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void notEnabled() {
|
||||||
|
assertTrue(configurer.getHandlerMapping().getUrlMap().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void enable() throws Exception {
|
||||||
|
configurer.enable();
|
||||||
|
SimpleUrlHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
||||||
|
DefaultServletHttpRequestHandler handler = (DefaultServletHttpRequestHandler) handlerMapping.getUrlMap().get("/**");
|
||||||
|
|
||||||
|
assertNotNull(handler);
|
||||||
|
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder());
|
||||||
|
|
||||||
|
handler.handleRequest(new MockHttpServletRequest(), response);
|
||||||
|
|
||||||
|
String expected = "default";
|
||||||
|
assertEquals("The ServletContext was not called with the default servlet name", expected, servletContext.url);
|
||||||
|
assertEquals("The request was not forwarded", expected, response.getForwardedUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void enableWithServletName() throws Exception {
|
||||||
|
configurer.enable("defaultServlet");
|
||||||
|
SimpleUrlHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
||||||
|
DefaultServletHttpRequestHandler handler = (DefaultServletHttpRequestHandler) handlerMapping.getUrlMap().get("/**");
|
||||||
|
|
||||||
|
assertNotNull(handler);
|
||||||
|
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder());
|
||||||
|
|
||||||
|
handler.handleRequest(new MockHttpServletRequest(), response);
|
||||||
|
|
||||||
|
String expected = "defaultServlet";
|
||||||
|
assertEquals("The ServletContext was not called with the default servlet name", expected, servletContext.url);
|
||||||
|
assertEquals("The request was not forwarded", expected, response.getForwardedUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DispatchingMockServletContext extends MockServletContext {
|
||||||
|
|
||||||
|
private String url;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public RequestDispatcher getNamedDispatcher(String url) {
|
||||||
|
this.url = url;
|
||||||
|
return new MockRequestDispatcher(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,168 @@
|
||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
import org.springframework.ui.ModelMap;
|
||||||
|
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.WebRequestHandlerInterceptorAdapter;
|
||||||
|
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
||||||
|
import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test fixture with a {@link InterceptorConfigurer}, two {@link HandlerInterceptor}s and two
|
||||||
|
* {@link WebRequestInterceptor}s.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
*/
|
||||||
|
public class InterceptorConfigurerTests {
|
||||||
|
|
||||||
|
private InterceptorConfigurer configurer;
|
||||||
|
|
||||||
|
private final HandlerInterceptor interceptor1 = new LocaleChangeInterceptor();
|
||||||
|
|
||||||
|
private final HandlerInterceptor interceptor2 = new ThemeChangeInterceptor();
|
||||||
|
|
||||||
|
private TestWebRequestInterceptor webRequestInterceptor1;
|
||||||
|
|
||||||
|
private TestWebRequestInterceptor webRequestInterceptor2;
|
||||||
|
|
||||||
|
private final MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
|
||||||
|
private final MockHttpServletResponse response = new MockHttpServletResponse();
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
configurer = new InterceptorConfigurer();
|
||||||
|
webRequestInterceptor1 = new TestWebRequestInterceptor();
|
||||||
|
webRequestInterceptor2 = new TestWebRequestInterceptor();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addInterceptor() {
|
||||||
|
configurer.addInterceptor(interceptor1);
|
||||||
|
HandlerInterceptor[] interceptors = getInterceptorsForPath(null);
|
||||||
|
assertArrayEquals(new HandlerInterceptor[] {interceptor1}, interceptors);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addInterceptors() {
|
||||||
|
configurer.addInterceptors(interceptor1, interceptor2);
|
||||||
|
HandlerInterceptor[] interceptors = getInterceptorsForPath(null);
|
||||||
|
assertArrayEquals(new HandlerInterceptor[] {interceptor1, interceptor2}, interceptors);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapInterceptor() {
|
||||||
|
configurer.mapInterceptor(new String[] {"/path1"}, interceptor1);
|
||||||
|
configurer.mapInterceptor(new String[] {"/path2"}, interceptor2);
|
||||||
|
|
||||||
|
assertArrayEquals(new HandlerInterceptor[] {interceptor1}, getInterceptorsForPath("/path1"));
|
||||||
|
assertArrayEquals(new HandlerInterceptor[] {interceptor2}, getInterceptorsForPath("/path2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapInterceptors() {
|
||||||
|
configurer.mapInterceptors(new String[] {"/path1"}, interceptor1, interceptor2);
|
||||||
|
|
||||||
|
assertArrayEquals(new HandlerInterceptor[] {interceptor1, interceptor2}, getInterceptorsForPath("/path1"));
|
||||||
|
assertArrayEquals(new HandlerInterceptor[] {}, getInterceptorsForPath("/path2"));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addWebRequestInterceptor() throws Exception {
|
||||||
|
configurer.addInterceptor(webRequestInterceptor1);
|
||||||
|
HandlerInterceptor[] interceptors = getInterceptorsForPath(null);
|
||||||
|
|
||||||
|
assertEquals(1, interceptors.length);
|
||||||
|
verifyAdaptedInterceptor(interceptors[0], webRequestInterceptor1);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void addWebRequestInterceptors() throws Exception {
|
||||||
|
configurer.addInterceptors(webRequestInterceptor1, webRequestInterceptor2);
|
||||||
|
HandlerInterceptor[] interceptors = getInterceptorsForPath(null);
|
||||||
|
|
||||||
|
assertEquals(2, interceptors.length);
|
||||||
|
verifyAdaptedInterceptor(interceptors[0], webRequestInterceptor1);
|
||||||
|
verifyAdaptedInterceptor(interceptors[1], webRequestInterceptor2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapWebRequestInterceptor() throws Exception {
|
||||||
|
configurer.mapInterceptor(new String[] {"/path1"}, webRequestInterceptor1);
|
||||||
|
configurer.mapInterceptor(new String[] {"/path2"}, webRequestInterceptor2);
|
||||||
|
|
||||||
|
HandlerInterceptor[] interceptors = getInterceptorsForPath("/path1");
|
||||||
|
assertEquals(1, interceptors.length);
|
||||||
|
verifyAdaptedInterceptor(interceptors[0], webRequestInterceptor1);
|
||||||
|
|
||||||
|
interceptors = getInterceptorsForPath("/path2");
|
||||||
|
assertEquals(1, interceptors.length);
|
||||||
|
verifyAdaptedInterceptor(interceptors[0], webRequestInterceptor2);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapWebRequestInterceptor2() throws Exception {
|
||||||
|
configurer.mapInterceptors(new String[] {"/path1"}, webRequestInterceptor1, webRequestInterceptor2);
|
||||||
|
|
||||||
|
HandlerInterceptor[] interceptors = getInterceptorsForPath("/path1");
|
||||||
|
assertEquals(2, interceptors.length);
|
||||||
|
verifyAdaptedInterceptor(interceptors[0], webRequestInterceptor1);
|
||||||
|
verifyAdaptedInterceptor(interceptors[1], webRequestInterceptor2);
|
||||||
|
|
||||||
|
assertEquals(0, getInterceptorsForPath("/path2").length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private HandlerInterceptor[] getInterceptorsForPath(String lookupPath) {
|
||||||
|
return configurer.getMappedInterceptors().getInterceptors(lookupPath, new AntPathMatcher());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyAdaptedInterceptor(HandlerInterceptor interceptor, TestWebRequestInterceptor webInterceptor)
|
||||||
|
throws Exception {
|
||||||
|
assertTrue(interceptor instanceof WebRequestHandlerInterceptorAdapter);
|
||||||
|
interceptor.preHandle(request, response, null);
|
||||||
|
assertTrue(webInterceptor.preHandleInvoked);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestWebRequestInterceptor implements WebRequestInterceptor {
|
||||||
|
|
||||||
|
private boolean preHandleInvoked = false;
|
||||||
|
|
||||||
|
public void preHandle(WebRequest request) throws Exception {
|
||||||
|
preHandleInvoked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void postHandle(WebRequest request, ModelMap model) throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void afterCompletion(WebRequest request, Exception ex) throws Exception {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* 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.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.assertSame;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
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.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||||
|
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||||
|
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.mvc.annotation.ResponseStatusExceptionResolver;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMethodAdapter;
|
||||||
|
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A test fixture with an {@link MvcConfiguration} and a mock {@link MvcConfigurer} for verifying delegation.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
*/
|
||||||
|
public class MvcConfigurationTests {
|
||||||
|
|
||||||
|
private MvcConfiguration mvcConfiguration;
|
||||||
|
|
||||||
|
private MvcConfigurer configurer;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
configurer = EasyMock.createMock(MvcConfigurer.class);
|
||||||
|
mvcConfiguration = new MvcConfiguration();
|
||||||
|
mvcConfiguration.setConfigurers(Arrays.asList(configurer));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void annotationHandlerAdapter() {
|
||||||
|
Capture<FormattingConversionService> conversionService = new Capture<FormattingConversionService>();
|
||||||
|
Capture<List<HandlerMethodArgumentResolver>> resolvers = new Capture<List<HandlerMethodArgumentResolver>>();
|
||||||
|
Capture<List<HandlerMethodReturnValueHandler>> handlers = new Capture<List<HandlerMethodReturnValueHandler>>();
|
||||||
|
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.configureMessageConverters(capture(converters));
|
||||||
|
replay(configurer);
|
||||||
|
|
||||||
|
RequestMappingHandlerMethodAdapter adapter = mvcConfiguration.requestMappingHandlerAdapter();
|
||||||
|
|
||||||
|
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer();
|
||||||
|
assertSame(conversionService.getValue(), initializer.getConversionService());
|
||||||
|
assertTrue(initializer.getValidator() instanceof LocalValidatorFactoryBean);
|
||||||
|
|
||||||
|
assertEquals(0, resolvers.getValue().size());
|
||||||
|
assertEquals(0, handlers.getValue().size());
|
||||||
|
assertTrue(converters.getValue().size() > 0);
|
||||||
|
assertEquals(converters.getValue(), adapter.getMessageConverters());
|
||||||
|
|
||||||
|
verify(configurer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void getCustomValidator() {
|
||||||
|
expect(configurer.getValidator()).andReturn(new LocalValidatorFactoryBean());
|
||||||
|
replay(configurer);
|
||||||
|
|
||||||
|
mvcConfiguration.validator();
|
||||||
|
|
||||||
|
verify(configurer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void configureValidator() {
|
||||||
|
expect(configurer.getValidator()).andReturn(null);
|
||||||
|
replay(configurer);
|
||||||
|
|
||||||
|
mvcConfiguration.validator();
|
||||||
|
|
||||||
|
verify(configurer);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handlerExceptionResolver() throws Exception {
|
||||||
|
Capture<List<HttpMessageConverter<?>>> converters = new Capture<List<HttpMessageConverter<?>>>();
|
||||||
|
Capture<List<HandlerExceptionResolver>> exceptionResolvers = new Capture<List<HandlerExceptionResolver>>();
|
||||||
|
|
||||||
|
configurer.configureMessageConverters(capture(converters));
|
||||||
|
configurer.configureHandlerExceptionResolvers(capture(exceptionResolvers));
|
||||||
|
replay(configurer);
|
||||||
|
|
||||||
|
mvcConfiguration.handlerExceptionResolver();
|
||||||
|
|
||||||
|
assertEquals(3, exceptionResolvers.getValue().size());
|
||||||
|
assertTrue(exceptionResolvers.getValue().get(0) instanceof ExceptionHandlerExceptionResolver);
|
||||||
|
assertTrue(exceptionResolvers.getValue().get(1) instanceof ResponseStatusExceptionResolver);
|
||||||
|
assertTrue(exceptionResolvers.getValue().get(2) instanceof DefaultHandlerExceptionResolver);
|
||||||
|
assertTrue(converters.getValue().size() > 0);
|
||||||
|
|
||||||
|
verify(configurer);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,89 @@
|
||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
|
import org.springframework.mock.web.MockHttpServletResponse;
|
||||||
|
import org.springframework.mock.web.MockServletContext;
|
||||||
|
import org.springframework.web.context.support.GenericWebApplicationContext;
|
||||||
|
import org.springframework.web.servlet.HandlerMapping;
|
||||||
|
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test fixture with a {@link ResourceConfigurer}.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
*/
|
||||||
|
public class ResourceConfigurerTests {
|
||||||
|
|
||||||
|
private ResourceConfigurer configurer;
|
||||||
|
|
||||||
|
private MockHttpServletResponse response;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
configurer = new ResourceConfigurer(new GenericWebApplicationContext(), new MockServletContext());
|
||||||
|
configurer.addPathMapping("/resources/**");
|
||||||
|
configurer.addResourceLocation("classpath:org/springframework/web/servlet/config/annotation/");
|
||||||
|
|
||||||
|
response = new MockHttpServletResponse();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noMappings() throws Exception {
|
||||||
|
configurer = new ResourceConfigurer(new GenericWebApplicationContext(), new MockServletContext());
|
||||||
|
assertTrue(configurer.getHandlerMapping().getUrlMap().isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapPathToLocation() throws Exception {
|
||||||
|
MockHttpServletRequest request = new MockHttpServletRequest();
|
||||||
|
request.setMethod("GET");
|
||||||
|
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/testStylesheet.css");
|
||||||
|
|
||||||
|
ResourceHttpRequestHandler handler = getResourceHandler("/resources/**");
|
||||||
|
handler.handleRequest(request, response);
|
||||||
|
|
||||||
|
assertEquals("test stylesheet content", response.getContentAsString());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void cachePeriod() {
|
||||||
|
assertEquals(-1, getResourceHandler("/resources/**").getCacheSeconds());
|
||||||
|
|
||||||
|
configurer.setCachePeriod(0);
|
||||||
|
assertEquals(0, getResourceHandler("/resources/**").getCacheSeconds());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void order() {
|
||||||
|
assertEquals(Integer.MAX_VALUE -1, configurer.getHandlerMapping().getOrder());
|
||||||
|
|
||||||
|
configurer.setOrder(0);
|
||||||
|
assertEquals(0, configurer.getHandlerMapping().getOrder());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResourceHttpRequestHandler getResourceHandler(String pathPattern) {
|
||||||
|
return (ResourceHttpRequestHandler) configurer.getHandlerMapping().getUrlMap().get(pathPattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,75 @@
|
||||||
|
/*
|
||||||
|
* 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.config.annotation;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||||
|
import org.springframework.web.servlet.mvc.ParameterizableViewController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test fixture with a {@link ViewControllerConfigurer}.
|
||||||
|
*
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
*/
|
||||||
|
public class ViewControllerConfigurerTests {
|
||||||
|
|
||||||
|
private ViewControllerConfigurer configurer;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
configurer = new ViewControllerConfigurer();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void noMappings() throws Exception {
|
||||||
|
Map<String, ?> urlMap = configurer.getHandlerMapping().getUrlMap();
|
||||||
|
assertTrue(urlMap.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapViewName() {
|
||||||
|
configurer.mapViewName("/path", "viewName");
|
||||||
|
Map<String, ?> urlMap = configurer.getHandlerMapping().getUrlMap();
|
||||||
|
ParameterizableViewController controller = (ParameterizableViewController) urlMap.get("/path");
|
||||||
|
assertNotNull(controller);
|
||||||
|
assertEquals("viewName", controller.getViewName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void mapViewNameByConvention() {
|
||||||
|
configurer.mapViewNameByConvention("/path");
|
||||||
|
Map<String, ?> urlMap = configurer.getHandlerMapping().getUrlMap();
|
||||||
|
ParameterizableViewController controller = (ParameterizableViewController) urlMap.get("/path");
|
||||||
|
assertNotNull(controller);
|
||||||
|
assertNull(controller.getViewName());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void order() {
|
||||||
|
SimpleUrlHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
||||||
|
assertEquals(1, handlerMapping.getOrder());
|
||||||
|
|
||||||
|
configurer.setOrder(2);
|
||||||
|
handlerMapping = configurer.getHandlerMapping();
|
||||||
|
assertEquals(2, handlerMapping.getOrder());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
test stylesheet content
|
||||||
Loading…
Reference in New Issue