SPR-8454 Introduce Registration style objects, rename several Spring MVC *Configurer helpers to *Registry, add more tests
This commit is contained in:
parent
889f8886f6
commit
ab033086f9
|
|
@ -21,75 +21,78 @@ import java.util.Map;
|
|||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.HttpRequestHandler;
|
||||
import org.springframework.web.servlet.DispatcherServlet;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
|
||||
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 EnableWebMvc}.
|
||||
* However, if you register your own HandlerMapping instance sure to set its "order" property to a value lower
|
||||
* than that of the {@link DefaultServletHttpRequestHandler}, which is {@link Integer#MAX_VALUE}.
|
||||
* Configures a request handler for serving static resources by forwarding the request to the Servlet container's
|
||||
* "default" Servlet. This is indended to be used when the Spring MVC {@link DispatcherServlet} is mapped to "/"
|
||||
* thus overriding the Servlet container's default handling of static resources. Since this handler is configured
|
||||
* at the lowest precedence, effectively it allows all other handler mappings to handle the request, and if none
|
||||
* of them do, this handler can forward it to the "default" Servlet.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*
|
||||
* @see ResourceConfigurer
|
||||
* @see DefaultServletHttpRequestHandler
|
||||
*/
|
||||
public class DefaultServletHandlerConfigurer {
|
||||
|
||||
private DefaultServletHttpRequestHandler requestHandler;
|
||||
|
||||
private final ServletContext servletContext;
|
||||
|
||||
private DefaultServletHttpRequestHandler handler;
|
||||
|
||||
/**
|
||||
* Create a {@link DefaultServletHandlerConfigurer} instance.
|
||||
* @param servletContext the ServletContext to use to configure the underlying DefaultServletHttpRequestHandler.
|
||||
*/
|
||||
public DefaultServletHandlerConfigurer(ServletContext servletContext) {
|
||||
Assert.notNull(servletContext, "A ServletContext is required to configure default servlet handling");
|
||||
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)}.
|
||||
* Enable forwarding to the "default" Servlet. When this method is used the {@link DefaultServletHttpRequestHandler}
|
||||
* will try to auto-detect the "default" Servlet name. Alternatively, you can specify the name of the default
|
||||
* Servlet via {@link #enable(String)}.
|
||||
* @see DefaultServletHttpRequestHandler
|
||||
*/
|
||||
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).
|
||||
* Enable forwarding to the "default" Servlet identified by the given name.
|
||||
* This is useful when the default Servlet cannot be auto-detected, for example when it has been manually configured.
|
||||
* @see DefaultServletHttpRequestHandler
|
||||
*/
|
||||
public void enable(String defaultServletName) {
|
||||
requestHandler = new DefaultServletHttpRequestHandler();
|
||||
requestHandler.setDefaultServletName(defaultServletName);
|
||||
requestHandler.setServletContext(servletContext);
|
||||
handler = new DefaultServletHttpRequestHandler();
|
||||
handler.setDefaultServletName(defaultServletName);
|
||||
handler.setServletContext(servletContext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link SimpleUrlHandlerMapping} instance ordered at {@link Integer#MAX_VALUE} containing a
|
||||
* {@link DefaultServletHttpRequestHandler} mapped to {@code /**}.
|
||||
* Return a handler mapping instance ordered at {@link Integer#MAX_VALUE} containing the
|
||||
* {@link DefaultServletHttpRequestHandler} instance mapped to {@code "/**"}; or {@code null} if
|
||||
* default servlet handling was not been enabled.
|
||||
*/
|
||||
protected SimpleUrlHandlerMapping getHandlerMapping() {
|
||||
protected AbstractHandlerMapping getHandlerMapping() {
|
||||
if (handler == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, HttpRequestHandler> urlMap = new HashMap<String, HttpRequestHandler>();
|
||||
urlMap.put("/**", handler);
|
||||
|
||||
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
|
||||
handlerMapping.setOrder(Integer.MAX_VALUE);
|
||||
handlerMapping.setUrlMap(getUrlMap());
|
||||
handlerMapping.setUrlMap(urlMap);
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
private Map<String, HttpRequestHandler> getUrlMap() {
|
||||
Map<String, HttpRequestHandler> urlMap = new HashMap<String, HttpRequestHandler>();
|
||||
if (requestHandler != null) {
|
||||
urlMap.put("/**", requestHandler);
|
||||
}
|
||||
return urlMap ;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -28,11 +28,13 @@ import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
|||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
|
||||
/**
|
||||
* A variant of {@link WebMvcConfigurationSupport} that delegates to one or more registered {@link WebMvcConfigurer}
|
||||
* implementations allowing each of them to customize the default Spring MVC configuration.
|
||||
* A variant of {@link WebMvcConfigurationSupport} that delegates to one or more registered
|
||||
* {@link WebMvcConfigurer}s allowing each of them to customize the default Spring MVC
|
||||
* code-based configuration.
|
||||
*
|
||||
* <p>This class is automatically imported when @{@link EnableWebMvc} is used on an @{@link Configuration} class.
|
||||
* In turn it detects all implementations of {@link WebMvcConfigurer} via autowiring and in turn delegates to them.
|
||||
* <p>This class is automatically imported when @{@link EnableWebMvc} is used to annotate
|
||||
* an @{@link Configuration} class. In turn it detects implementations of {@link WebMvcConfigurer}
|
||||
* via autowiring and delegates to them.
|
||||
*
|
||||
* @see EnableWebMvc
|
||||
* @see WebMvcConfigurer
|
||||
|
|
@ -54,18 +56,18 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
|
|||
}
|
||||
|
||||
@Override
|
||||
protected final void configureInterceptors(InterceptorConfigurer configurer) {
|
||||
configurers.configureInterceptors(configurer);
|
||||
protected final void addInterceptors(InterceptorRegistry registry) {
|
||||
configurers.addInterceptors(registry);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void configureViewControllers(ViewControllerConfigurer configurer) {
|
||||
configurers.configureViewControllers(configurer);
|
||||
protected final void addViewControllers(ViewControllerRegistry registry) {
|
||||
configurers.addViewControllers(registry);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void configureResourceHandling(ResourceConfigurer configurer) {
|
||||
configurers.configureResourceHandling(configurer);
|
||||
protected final void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
configurers.addResourceHandlers(registry);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -24,9 +24,8 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||
|
||||
/**
|
||||
* Enables default Spring MVC configuration and registers Spring MVC infrastructure components expected by the
|
||||
* {@link DispatcherServlet}. Add this annotation to an application @{@link Configuration} class. It will in
|
||||
* turn import the @{@link Configuration} class {@link DelegatingWebMvcConfiguration}, which provides default Spring MVC
|
||||
* configuration.
|
||||
* {@link DispatcherServlet}. Use this annotation on an @{@link Configuration} class. In turn that will
|
||||
* import {@link DelegatingWebMvcConfiguration}, which provides default Spring MVC configuration.
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableWebMvc
|
||||
|
|
@ -39,9 +38,9 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||
* }
|
||||
* </pre>
|
||||
* <p>To customize the imported configuration implement {@link WebMvcConfigurer}, or more conveniently extend
|
||||
* {@link WebMvcConfigurerAdapter} overriding specific methods. Your @{@link Configuration} class and any other
|
||||
* Spring bean that implements {@link WebMvcConfigurer} will be detected and given an opportunity to customize
|
||||
* the default Spring MVC configuration through the callback methods on the {@link WebMvcConfigurer} interface.
|
||||
* {@link WebMvcConfigurerAdapter} overriding specific methods only. Any @{@link Configuration} class that
|
||||
* implements {@link WebMvcConfigurer} will be detected by {@link DelegatingWebMvcConfiguration} and given
|
||||
* an opportunity to customize the default Spring MVC code-based configuration.
|
||||
* <pre class="code">
|
||||
* @Configuration
|
||||
* @EnableWebMvc
|
||||
|
|
@ -52,7 +51,7 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||
* public class MyConfiguration extends WebMvcConfigurerAdapter {
|
||||
*
|
||||
* @Override
|
||||
* public void registerFormatters(FormatterRegistry formatterRegistry) {
|
||||
* public void addFormatters(FormatterRegistry formatterRegistry) {
|
||||
* formatterRegistry.addConverter(new MyConverter());
|
||||
* }
|
||||
*
|
||||
|
|
@ -61,7 +60,7 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||
* converters.add(new MyHttpMessageConverter());
|
||||
* }
|
||||
*
|
||||
* ...
|
||||
* // @Override methods ...
|
||||
*
|
||||
* }
|
||||
* </pre>
|
||||
|
|
|
|||
|
|
@ -1,134 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.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.handler.MappedInterceptor;
|
||||
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
|
||||
|
||||
/**
|
||||
* Helps with configuring an ordered set of Spring MVC interceptors of type {@link HandlerInterceptor} or
|
||||
* {@link WebRequestInterceptor}. Interceptors can be registered with a set of path patterns.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*/
|
||||
public class InterceptorConfigurer {
|
||||
|
||||
private final List<Object> interceptors = new ArrayList<Object>();
|
||||
|
||||
/**
|
||||
* Add a {@link HandlerInterceptor} that should apply to any request.
|
||||
*/
|
||||
public void addInterceptor(HandlerInterceptor interceptor) {
|
||||
register(interceptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link WebRequestInterceptor} that should apply to any request.
|
||||
*/
|
||||
public void addInterceptor(WebRequestInterceptor interceptor) {
|
||||
register(asHandlerInterceptorArray(interceptor));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link HandlerInterceptor}s that should apply to any request.
|
||||
*/
|
||||
public void addInterceptors(HandlerInterceptor... interceptors) {
|
||||
register( interceptors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link WebRequestInterceptor}s that should apply to any request.
|
||||
*/
|
||||
public void addInterceptors(WebRequestInterceptor... interceptors) {
|
||||
register(asHandlerInterceptorArray(interceptors));
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link HandlerInterceptor} with a set of URL path patterns it should apply to.
|
||||
*/
|
||||
public void mapInterceptor(String[] pathPatterns, HandlerInterceptor interceptor) {
|
||||
registerMappedInterceptors(pathPatterns, interceptor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a {@link WebRequestInterceptor} with a set of URL path patterns it should apply to.
|
||||
*/
|
||||
public void mapInterceptor(String[] pathPatterns, WebRequestInterceptor interceptors) {
|
||||
registerMappedInterceptors(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) {
|
||||
registerMappedInterceptors(pathPatterns, interceptors);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add {@link WebRequestInterceptor}s with a set of URL path patterns they should apply to.
|
||||
*/
|
||||
public void mapInterceptors(String[] pathPatterns, WebRequestInterceptor... interceptors) {
|
||||
registerMappedInterceptors(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 internally.
|
||||
* @param interceptors one or more interceptors to be stored
|
||||
*/
|
||||
protected void register(HandlerInterceptor...interceptors) {
|
||||
Assert.notEmpty(interceptors, "At least one interceptor must be provided");
|
||||
for (HandlerInterceptor interceptor : interceptors) {
|
||||
this.interceptors.add(interceptor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 registerMappedInterceptors(String[] pathPatterns, HandlerInterceptor...interceptors) {
|
||||
Assert.notEmpty(interceptors, "At least one interceptor must be provided");
|
||||
Assert.notEmpty(pathPatterns, "Path patterns must be provided");
|
||||
for (HandlerInterceptor interceptor : interceptors) {
|
||||
this.interceptors.add(new MappedInterceptor(pathPatterns, interceptor));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all registered interceptors.
|
||||
*/
|
||||
protected List<Object> getInterceptors() {
|
||||
return interceptors;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.handler.MappedInterceptor;
|
||||
|
||||
/**
|
||||
* Encapsulates a {@link HandlerInterceptor} and an optional list of URL patterns.
|
||||
* Results in the creation of a {@link MappedInterceptor} if URL patterns are provided.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Keith Donald
|
||||
* @since 3.1
|
||||
*/
|
||||
public class InterceptorRegistration {
|
||||
|
||||
private final HandlerInterceptor interceptor;
|
||||
|
||||
private final List<String> pathPatterns = new ArrayList<String>();
|
||||
|
||||
/**
|
||||
* Creates an {@link InterceptorRegistration} instance.
|
||||
*/
|
||||
public InterceptorRegistration(HandlerInterceptor interceptor) {
|
||||
Assert.notNull(interceptor, "Interceptor is required");
|
||||
this.interceptor = interceptor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds one or more URL patterns to which the registered interceptor should apply to.
|
||||
* If no URL patterns are provided, the interceptor applies to all paths.
|
||||
*/
|
||||
public void addPathPatterns(String... pathPatterns) {
|
||||
this.pathPatterns.addAll(Arrays.asList(pathPatterns));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the underlying interceptor. If URL patterns are provided the returned type is
|
||||
* {@link MappedInterceptor}; otherwise {@link HandlerInterceptor}.
|
||||
*/
|
||||
protected Object getInterceptor() {
|
||||
if (pathPatterns.isEmpty()) {
|
||||
return interceptor;
|
||||
}
|
||||
return new MappedInterceptor(pathPatterns.toArray(new String[pathPatterns.size()]), interceptor);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.web.context.request.WebRequestInterceptor;
|
||||
import org.springframework.web.servlet.HandlerInterceptor;
|
||||
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter;
|
||||
|
||||
/**
|
||||
* Stores and provides access to a list of interceptors. For each interceptor you can optionally
|
||||
* specify one or more URL patterns it applies to.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Keith Donald
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
public class InterceptorRegistry {
|
||||
|
||||
private final List<InterceptorRegistration> registrations = new ArrayList<InterceptorRegistration>();
|
||||
|
||||
/**
|
||||
* Adds the provided {@link HandlerInterceptor}.
|
||||
* @param interceptor the interceptor to add
|
||||
* @return An {@link InterceptorRegistration} that allows you optionally configure the
|
||||
* registered interceptor further for example adding URL patterns it should apply to.
|
||||
*/
|
||||
public InterceptorRegistration addInterceptor(HandlerInterceptor interceptor) {
|
||||
InterceptorRegistration registration = new InterceptorRegistration(interceptor);
|
||||
registrations.add(registration);
|
||||
return registration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the provided {@link WebRequestInterceptor}.
|
||||
* @param interceptor the interceptor to add
|
||||
* @return An {@link InterceptorRegistration} that allows you optionally configure the
|
||||
* registered interceptor further for example adding URL patterns it should apply to.
|
||||
*/
|
||||
public InterceptorRegistration addWebRequestInterceptor(WebRequestInterceptor interceptor) {
|
||||
WebRequestHandlerInterceptorAdapter adapted = new WebRequestHandlerInterceptorAdapter(interceptor);
|
||||
InterceptorRegistration registration = new InterceptorRegistration(adapted);
|
||||
registrations.add(registration);
|
||||
return registration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all registered interceptors.
|
||||
*/
|
||||
protected List<Object> getInterceptors() {
|
||||
List<Object> interceptors = new ArrayList<Object>();
|
||||
for (InterceptorRegistration registration : registrations) {
|
||||
interceptors.add(registration.getInterceptor());
|
||||
}
|
||||
return interceptors ;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.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,105 @@
|
|||
/*
|
||||
* 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.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
|
||||
|
||||
/**
|
||||
* Encapsulates information required to create a resource handlers.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Keith Donald
|
||||
*
|
||||
* @since 3.1
|
||||
*/
|
||||
public class ResourceHandlerRegistration {
|
||||
|
||||
private final ResourceLoader resourceLoader;
|
||||
|
||||
private final String[] pathPatterns;
|
||||
|
||||
private final List<Resource> locations = new ArrayList<Resource>();
|
||||
|
||||
private Integer cachePeriod;
|
||||
|
||||
/**
|
||||
* Create a {@link ResourceHandlerRegistration} instance.
|
||||
* @param resourceLoader a resource loader for turning a String location into a {@link Resource}
|
||||
* @param pathPatterns one or more resource URL path patterns
|
||||
*/
|
||||
public ResourceHandlerRegistration(ResourceLoader resourceLoader, String... pathPatterns) {
|
||||
Assert.notEmpty(pathPatterns, "At least one path pattern is required for resource handling.");
|
||||
this.resourceLoader = resourceLoader;
|
||||
this.pathPatterns = pathPatterns;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ResourceHandlerRegistration} instance for chained method invocation
|
||||
*/
|
||||
public ResourceHandlerRegistration addResourceLocations(String...resourceLocations) {
|
||||
for (String location : resourceLocations) {
|
||||
this.locations.add(resourceLoader.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 ResourceHandlerRegistration} instance for chained method invocation
|
||||
*/
|
||||
public ResourceHandlerRegistration setCachePeriod(Integer cachePeriod) {
|
||||
this.cachePeriod = cachePeriod;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL path patterns for the resource handler.
|
||||
*/
|
||||
protected String[] getPathPatterns() {
|
||||
return pathPatterns;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link ResourceHttpRequestHandler} instance.
|
||||
*/
|
||||
protected ResourceHttpRequestHandler getRequestHandler() {
|
||||
Assert.isTrue(!CollectionUtils.isEmpty(locations), "At least one location is required for resource handling.");
|
||||
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
|
||||
requestHandler.setLocations(locations);
|
||||
if (cachePeriod != null) {
|
||||
requestHandler.setCacheSeconds(cachePeriod);
|
||||
}
|
||||
return requestHandler;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* 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.util.Assert;
|
||||
import org.springframework.web.HttpRequestHandler;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
|
||||
|
||||
/**
|
||||
* Stores registrations of resource handlers 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 create a resource handler, use {@link #addResourceHandler(String...)} providing the URL path patterns
|
||||
* for which the handler should be invoked to serve static resources (e.g. {@code "/resources/**"}).
|
||||
*
|
||||
* <p>Then use additional methods on the returned {@link ResourceHandlerRegistration} to add one or more
|
||||
* locations from which to serve static content from (e.g. {{@code "/"},
|
||||
* {@code "classpath:/META-INF/public-web-resources/"}}) or to specify a cache period for served resources.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
*
|
||||
* @see DefaultServletHandlerConfigurer
|
||||
*/
|
||||
public class ResourceHandlerRegistry {
|
||||
|
||||
private final ServletContext servletContext;
|
||||
|
||||
private final ApplicationContext applicationContext;
|
||||
|
||||
private final List<ResourceHandlerRegistration> registrations = new ArrayList<ResourceHandlerRegistration>();
|
||||
|
||||
private int order = Integer.MAX_VALUE -1;
|
||||
|
||||
public ResourceHandlerRegistry(ApplicationContext applicationContext, ServletContext servletContext) {
|
||||
Assert.notNull(applicationContext, "ApplicationContext is required");
|
||||
this.applicationContext = applicationContext;
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a resource handler for serving static resources based on the specified URL path patterns.
|
||||
* The handler will be invoked for every incoming request that matches to one of the specified path patterns.
|
||||
* @return A {@link ResourceHandlerRegistration} to use to further configure the registered resource handler.
|
||||
*/
|
||||
public ResourceHandlerRegistration addResourceHandler(String... pathPatterns) {
|
||||
ResourceHandlerRegistration registration = new ResourceHandlerRegistration(applicationContext, pathPatterns);
|
||||
registrations.add(registration);
|
||||
return registration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the order to use for resource handling relative to other {@link HandlerMapping}s configured in
|
||||
* the Spring MVC application context. The default value used is {@code Integer.MAX_VALUE-1}.
|
||||
*/
|
||||
public ResourceHandlerRegistry setOrder(int order) {
|
||||
this.order = order;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a handler mapping with the mapped resource handlers; or {@code null} in case of no registrations.
|
||||
*/
|
||||
protected AbstractHandlerMapping getHandlerMapping() {
|
||||
if (registrations.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, HttpRequestHandler> urlMap = new LinkedHashMap<String, HttpRequestHandler>();
|
||||
for (ResourceHandlerRegistration registration : registrations) {
|
||||
for (String pathPattern : registration.getPathPatterns()) {
|
||||
ResourceHttpRequestHandler requestHandler = registration.getRequestHandler();
|
||||
requestHandler.setServletContext(servletContext);
|
||||
requestHandler.setApplicationContext(applicationContext);
|
||||
urlMap.put(pathPattern, requestHandler);
|
||||
}
|
||||
}
|
||||
|
||||
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
|
||||
handlerMapping.setOrder(order);
|
||||
handlerMapping.setUrlMap(urlMap);
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,87 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2011 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.servlet.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,70 @@
|
|||
/*
|
||||
* 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 org.springframework.util.Assert;
|
||||
import org.springframework.web.servlet.RequestToViewNameTranslator;
|
||||
import org.springframework.web.servlet.mvc.ParameterizableViewController;
|
||||
|
||||
/**
|
||||
* Encapsulates information required to create a view controller.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Keith Donald
|
||||
* @since 3.1
|
||||
*/
|
||||
public class ViewControllerRegistration {
|
||||
|
||||
private final String urlPath;
|
||||
|
||||
private String viewName;
|
||||
|
||||
/**
|
||||
* Creates a {@link ViewControllerRegistration} with the given URL path. When a request matches
|
||||
* to the given URL path this view controller will process it.
|
||||
*/
|
||||
public ViewControllerRegistration(String urlPath) {
|
||||
Assert.notNull(urlPath, "A URL path is required to create a view controller.");
|
||||
this.urlPath = urlPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the view name to use for this view controller. This field is optional. If not specified the
|
||||
* view controller will return a {@code null} view name, which will be resolved through the configured
|
||||
* {@link RequestToViewNameTranslator}. By default that means "/foo/bar" would resolve to "foo/bar".
|
||||
*/
|
||||
public void setViewName(String viewName) {
|
||||
this.viewName = viewName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the URL path for the view controller.
|
||||
*/
|
||||
protected String getUrlPath() {
|
||||
return urlPath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the view controllers.
|
||||
*/
|
||||
protected Object getViewController() {
|
||||
ParameterizableViewController controller = new ParameterizableViewController();
|
||||
controller.setViewName(viewName);
|
||||
return controller;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/*
|
||||
* 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 org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
|
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
||||
|
||||
/**
|
||||
* Stores registrations of view controllers. A view controller does nothing more than return a specified
|
||||
* view name. It saves you from having to write a controller when you want to forward the request straight
|
||||
* through to a view such as a JSP.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Keith Donald
|
||||
* @since 3.1
|
||||
*/
|
||||
public class ViewControllerRegistry {
|
||||
|
||||
private final List<ViewControllerRegistration> registrations = new ArrayList<ViewControllerRegistration>();
|
||||
|
||||
private int order = 1;
|
||||
|
||||
public ViewControllerRegistration addViewController(String urlPath) {
|
||||
ViewControllerRegistration registration = new ViewControllerRegistration(urlPath);
|
||||
registrations.add(registration);
|
||||
return registration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the order to use for ViewControllers mappings relative to other {@link HandlerMapping}s
|
||||
* configured in the Spring MVC application context. The default value for view controllers is 1,
|
||||
* which is 1 higher than the value used for annotated controllers.
|
||||
*/
|
||||
public void setOrder(int order) {
|
||||
this.order = order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a handler mapping with the mapped ViewControllers; or {@code null} in case of no registrations.
|
||||
*/
|
||||
protected AbstractHandlerMapping getHandlerMapping() {
|
||||
if (registrations.isEmpty()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Map<String, Object> urlMap = new LinkedHashMap<String, Object>();
|
||||
for (ViewControllerRegistration registration : registrations) {
|
||||
urlMap.put(registration.getUrlPath(), registration.getViewController());
|
||||
}
|
||||
|
||||
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
|
||||
handlerMapping.setOrder(order);
|
||||
handlerMapping.setUrlMap(urlMap);
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -20,6 +20,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
|
|
@ -46,7 +47,6 @@ 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.MessageCodesResolver;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.web.HttpRequestHandler;
|
||||
import org.springframework.web.bind.annotation.ExceptionHandler;
|
||||
|
|
@ -59,10 +59,10 @@ import org.springframework.web.servlet.DispatcherServlet;
|
|||
import org.springframework.web.servlet.HandlerAdapter;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.HandlerMapping;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
|
||||
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.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.Controller;
|
||||
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
|
||||
|
|
@ -75,27 +75,25 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv
|
|||
/**
|
||||
* A base class that provides default configuration for Spring MVC applications by registering Spring MVC
|
||||
* infrastructure components to be detected by the {@link DispatcherServlet}. Typically applications should not
|
||||
* have to start by extending this class. A much easier place to start is to annotate your @{@link Configuration}
|
||||
* class with @{@link EnableWebMvc}. See @{@link EnableWebMvc} and {@link WebMvcConfigurer}.
|
||||
* have to extend this class. A more likely place to start is to annotate an @{@link Configuration}
|
||||
* class with @{@link EnableWebMvc} (see @{@link EnableWebMvc} and {@link WebMvcConfigurer} for details).
|
||||
*
|
||||
* <p>If using @{@link EnableWebMvc} and extending from {@link WebMvcConfigurerAdapter} does not give you the level
|
||||
* of flexibility you need, consider extending directly from this class instead. Remember to add @{@link Configuration}
|
||||
* to your subclass and @{@link Bean} to any superclass @{@link Bean} methods you choose to override. A few example
|
||||
* reasons for extending this class include providing a custom {@link MessageCodesResolver}, changing the order of
|
||||
* {@link HandlerMapping} instances, plugging in a variant of any of the beans provided by this class, and so on.
|
||||
* <p>If using @{@link EnableWebMvc} does not give you all you need, consider extending directly from this
|
||||
* class. Remember to add @{@link Configuration} to your subclass and @{@link Bean} to any superclass
|
||||
* @{@link Bean} methods you choose to override.
|
||||
*
|
||||
* <p>This class registers the following {@link HandlerMapping}s:</p>
|
||||
* <ul>
|
||||
* <li>{@link RequestMappingHandlerMapping} 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 HandlerMapping} 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.
|
||||
* <li>{@link HandlerMapping} ordered at {@code Integer.MAX_VALUE-1} to serve static resource requests.
|
||||
* <li>{@link HandlerMapping} ordered at {@code Integer.MAX_VALUE} to forward requests to the default servlet.
|
||||
* </ul>
|
||||
*
|
||||
* <p>Registers {@link HandlerAdapter}s:
|
||||
* <p>Registers these {@link HandlerAdapter}s:
|
||||
* <ul>
|
||||
* <li>{@link RequestMappingHandlerAdapter} for processing requests using annotated controller methods.
|
||||
* <li>{@link RequestMappingHandlerAdapter} for processing requests with 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>
|
||||
|
|
@ -107,7 +105,7 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv
|
|||
* <li>{@link DefaultHandlerExceptionResolver} for resolving known Spring exception types
|
||||
* </ul>
|
||||
*
|
||||
* <p>Registers the following other instances:
|
||||
* <p>Registers these other instances:
|
||||
* <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.
|
||||
|
|
@ -143,57 +141,53 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
|||
*/
|
||||
@Bean
|
||||
public RequestMappingHandlerMapping requestMappingHandlerMapping() {
|
||||
RequestMappingHandlerMapping mapping = new RequestMappingHandlerMapping();
|
||||
mapping.setInterceptors(getInterceptors());
|
||||
mapping.setOrder(0);
|
||||
return mapping;
|
||||
RequestMappingHandlerMapping handlerMapping = new RequestMappingHandlerMapping();
|
||||
handlerMapping.setOrder(0);
|
||||
handlerMapping.setInterceptors(getInterceptors());
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides access to the shared handler interceptors used to configure {@link HandlerMapping} instances with.
|
||||
* This method cannot be overridden, use {@link #configureInterceptors(InterceptorConfigurer)} instead.
|
||||
* This method cannot be overridden, use {@link #addInterceptors(InterceptorRegistry)} instead.
|
||||
*/
|
||||
protected final Object[] getInterceptors() {
|
||||
if (interceptors == null) {
|
||||
InterceptorConfigurer configurer = new InterceptorConfigurer();
|
||||
configureInterceptors(configurer);
|
||||
configurer.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService()));
|
||||
interceptors = configurer.getInterceptors();
|
||||
InterceptorRegistry registry = new InterceptorRegistry();
|
||||
addInterceptors(registry);
|
||||
registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService()));
|
||||
interceptors = registry.getInterceptors();
|
||||
}
|
||||
return interceptors.toArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to configure the Spring MVC interceptors to use. Interceptors allow requests to
|
||||
* be pre- and post-processed before and after controller invocation. They can be registered to apply
|
||||
* to all requests or be limited to a set of path patterns.
|
||||
* @see InterceptorConfigurer
|
||||
* Override this method to add Spring MVC interceptors for pre/post-processing of controller invocation.
|
||||
* @see InterceptorRegistry
|
||||
*/
|
||||
protected void configureInterceptors(InterceptorConfigurer configurer) {
|
||||
protected void addInterceptors(InterceptorRegistry registry) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SimpleUrlHandlerMapping} ordered at 1 to map URL paths directly to view names.
|
||||
* To configure view controllers see {@link #configureViewControllers(ViewControllerConfigurer)}.
|
||||
* Returns a handler mapping ordered at 1 to map URL paths directly to view names.
|
||||
* To configure view controllers, override {@link #addViewControllers(ViewControllerRegistry)}.
|
||||
*/
|
||||
@Bean
|
||||
public SimpleUrlHandlerMapping viewControllerHandlerMapping() {
|
||||
ViewControllerConfigurer configurer = new ViewControllerConfigurer();
|
||||
configurer.setOrder(1);
|
||||
configureViewControllers(configurer);
|
||||
public HandlerMapping viewControllerHandlerMapping() {
|
||||
ViewControllerRegistry registry = new ViewControllerRegistry();
|
||||
addViewControllers(registry);
|
||||
|
||||
SimpleUrlHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
||||
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
|
||||
handlerMapping = handlerMapping != null ? handlerMapping : new EmptyHandlerMapping();
|
||||
handlerMapping.setInterceptors(getInterceptors());
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to configure 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.
|
||||
* @see ViewControllerConfigurer
|
||||
* Override this method to add view controllers.
|
||||
* @see ViewControllerRegistry
|
||||
*/
|
||||
protected void configureViewControllers(ViewControllerConfigurer configurer) {
|
||||
protected void addViewControllers(ViewControllerRegistry registry) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -208,53 +202,50 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
|||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SimpleUrlHandlerMapping} ordered at Integer.MAX_VALUE-1 to serve static resource requests.
|
||||
* To configure resource handling, see {@link #configureResourceHandling(ResourceConfigurer)}.
|
||||
* Returns a handler mapping ordered at Integer.MAX_VALUE-1 with mapped resource handlers.
|
||||
* To configure resource handling, override {@link #addResourceHandlers(ResourceHandlerRegistry)}.
|
||||
*/
|
||||
@Bean
|
||||
public SimpleUrlHandlerMapping resourceHandlerMapping() {
|
||||
ResourceConfigurer configurer = new ResourceConfigurer(applicationContext, servletContext);
|
||||
configurer.setOrder(Integer.MAX_VALUE-1);
|
||||
configureResourceHandling(configurer);
|
||||
return configurer.getHandlerMapping();
|
||||
public HandlerMapping resourceHandlerMapping() {
|
||||
ResourceHandlerRegistry registry = new ResourceHandlerRegistry(applicationContext, servletContext);
|
||||
addResourceHandlers(registry);
|
||||
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
|
||||
handlerMapping = handlerMapping != null ? handlerMapping : new EmptyHandlerMapping();
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to 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.
|
||||
* @see ResourceConfigurer
|
||||
* Override this method to add resource handlers for serving static resources.
|
||||
* @see ResourceHandlerRegistry
|
||||
*/
|
||||
protected void configureResourceHandling(ResourceConfigurer configurer) {
|
||||
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link SimpleUrlHandlerMapping} ordered at Integer.MAX_VALUE to serve static resources by
|
||||
* forwarding to the Servlet container's default servlet. To configure default servlet handling see
|
||||
* Returns a handler mapping ordered at Integer.MAX_VALUE with a mapped default servlet handler.
|
||||
* To configure "default" Servlet handling, override
|
||||
* {@link #configureDefaultServletHandling(DefaultServletHandlerConfigurer)}.
|
||||
*/
|
||||
@Bean
|
||||
public SimpleUrlHandlerMapping defaultServletHandlerMapping() {
|
||||
public HandlerMapping defaultServletHandlerMapping() {
|
||||
DefaultServletHandlerConfigurer configurer = new DefaultServletHandlerConfigurer(servletContext);
|
||||
configureDefaultServletHandling(configurer);
|
||||
return configurer.getHandlerMapping();
|
||||
AbstractHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
||||
handlerMapping = handlerMapping != null ? handlerMapping : new EmptyHandlerMapping();
|
||||
return handlerMapping;
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to 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.
|
||||
* Override this method to configure "default" Servlet handling.
|
||||
* @see DefaultServletHandlerConfigurer
|
||||
*/
|
||||
protected void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a {@link RequestMappingHandlerAdapter} for processing requests using annotated controller methods.
|
||||
* Also see the following other methods as an alternative to overriding this method:
|
||||
* Returns a {@link RequestMappingHandlerAdapter} for processing requests through annotated controller methods.
|
||||
* Consider overriding one of these other more fine-grained methods:
|
||||
* <ul>
|
||||
* <li>{@link #initWebBindingInitializer()} for configuring data binding globally.
|
||||
* <li>{@link #addArgumentResolvers(List)} for adding custom argument resolvers.
|
||||
* <li>{@link #addReturnValueHandlers(List)} for adding custom return value handlers.
|
||||
* <li>{@link #configureMessageConverters(List)} for adding custom message converters.
|
||||
|
|
@ -265,7 +256,6 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
|||
ConfigurableWebBindingInitializer webBindingInitializer = new ConfigurableWebBindingInitializer();
|
||||
webBindingInitializer.setConversionService(mvcConversionService());
|
||||
webBindingInitializer.setValidator(mvcValidator());
|
||||
configureWebBindingInitializer(webBindingInitializer);
|
||||
|
||||
List<HandlerMethodArgumentResolver> argumentResolvers = new ArrayList<HandlerMethodArgumentResolver>();
|
||||
addArgumentResolvers(argumentResolvers);
|
||||
|
|
@ -282,28 +272,21 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
|||
}
|
||||
|
||||
/**
|
||||
* Override this method to customize the {@link ConfigurableWebBindingInitializer} the
|
||||
* {@link RequestMappingHandlerAdapter} is configured with.
|
||||
*/
|
||||
protected void configureWebBindingInitializer(ConfigurableWebBindingInitializer webBindingInitializer) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to add custom argument resolvers to use in addition to the ones registered by default
|
||||
* internally by the {@link RequestMappingHandlerAdapter}.
|
||||
* <p>Generally custom argument resolvers are invoked first. However this excludes default argument resolvers that
|
||||
* rely on the presence of annotations (e.g. {@code @RequestParameter}, {@code @PathVariable}, etc.). Those
|
||||
* argument resolvers are not customizable without configuring RequestMappingHandlerAdapter directly.
|
||||
* Add custom {@link HandlerMethodArgumentResolver}s to use in addition to the ones registered by default.
|
||||
* <p>Custom argument resolvers are invoked before built-in resolvers except for those that rely on the presence
|
||||
* of annotations (e.g. {@code @RequestParameter}, {@code @PathVariable}, etc.). The latter can be customized
|
||||
* by configuring the {@link RequestMappingHandlerAdapter} directly.
|
||||
* @param argumentResolvers the list of custom converters; initially an empty list.
|
||||
*/
|
||||
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Override this method to add custom return value handlers to use in addition to the ones registered by default
|
||||
* internally by the {@link RequestMappingHandlerAdapter}.
|
||||
* <p>Generally custom return value handlers are invoked first. However this excludes default return value handlers
|
||||
* that rely on the presence of annotations (e.g. {@code @ResponseBody}, {@code @ModelAttribute}, etc.). Those
|
||||
* handlers are not customizable without configuring RequestMappingHandlerAdapter directly.
|
||||
* Add custom {@link HandlerMethodReturnValueHandler}s in addition to the ones registered by default.
|
||||
* <p>Custom return value handlers are invoked before built-in ones except for those that rely on the presence
|
||||
* of annotations (e.g. {@code @ResponseBody}, {@code @ModelAttribute}, etc.). The latter can be customized
|
||||
* by configuring the {@link RequestMappingHandlerAdapter} directly.
|
||||
* @param returnValueHandlers the list of custom handlers; initially an empty list.
|
||||
*/
|
||||
protected void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
||||
}
|
||||
|
|
@ -311,8 +294,8 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
|||
/**
|
||||
* Provides access to the shared {@link HttpMessageConverter}s used by the
|
||||
* {@link RequestMappingHandlerAdapter} and the {@link ExceptionHandlerExceptionResolver}.
|
||||
* This method cannot be extended directly, use {@link #configureMessageConverters(List)} add custom converters.
|
||||
* For the list of message converters added by default see {@link #addDefaultHttpMessageConverters(List)}.
|
||||
* This method cannot be overridden. Use {@link #configureMessageConverters(List)} instead.
|
||||
* Also see {@link #addDefaultHttpMessageConverters(List)} that can be used to add default message converters.
|
||||
*/
|
||||
protected final List<HttpMessageConverter<?>> getMessageConverters() {
|
||||
if (messageConverters == null) {
|
||||
|
|
@ -328,16 +311,16 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
|||
/**
|
||||
* Override this method to add custom {@link HttpMessageConverter}s to use with
|
||||
* the {@link RequestMappingHandlerAdapter} and the {@link ExceptionHandlerExceptionResolver}.
|
||||
* If any converters are added through this method, default converters are added automatically.
|
||||
* See {@link #addDefaultHttpMessageConverters(List)} for adding default converters to the list.
|
||||
* @param messageConverters the list to add converters to
|
||||
* Adding converters to the list turns off the default converters that would otherwise be registered by default.
|
||||
* Also see {@link #addDefaultHttpMessageConverters(List)} that can be used to add default message converters.
|
||||
* @param converters a list to add message converters to; initially an empty list.
|
||||
*/
|
||||
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
}
|
||||
|
||||
/**
|
||||
* A method available to subclasses for adding default {@link HttpMessageConverter}s.
|
||||
* @param messageConverters the list to add converters to
|
||||
* A method available to subclasses to add default {@link HttpMessageConverter}s.
|
||||
* @param messageConverters the list to add the default message converters to
|
||||
*/
|
||||
protected final void addDefaultHttpMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
|
||||
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
|
||||
|
|
@ -382,8 +365,7 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
|||
|
||||
/**
|
||||
* Returns {@link Validator} for validating {@code @ModelAttribute} and {@code @RequestBody} arguments of
|
||||
* annotated controller methods. This method is closed for extension. Use {@link #getValidator()} to
|
||||
* provide a custom validator.
|
||||
* annotated controller methods. To configure a custom validation, override {@link #getValidator()}.
|
||||
*/
|
||||
@Bean
|
||||
Validator mvcValidator() {
|
||||
|
|
@ -415,10 +397,7 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
|||
}
|
||||
|
||||
/**
|
||||
* Override this method to provide a custom {@link Validator} type. If this method returns {@code null}, by
|
||||
* a check is made for the presence of a JSR-303 implementation on the classpath - if available a
|
||||
* {@link org.springframework.validation.beanvalidation.LocalValidatorFactoryBean} instance is created.
|
||||
* Otherwise if no JSR-303 implementation is detected, a no-op {@link Validator} is returned instead.
|
||||
* Override this method to provide a custom {@link Validator}.
|
||||
*/
|
||||
protected Validator getValidator() {
|
||||
return null;
|
||||
|
|
@ -442,8 +421,7 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
|||
|
||||
/**
|
||||
* Returns a {@link HandlerExceptionResolverComposite} that contains a list of exception resolvers.
|
||||
* This method is closed for extension. Use {@link #configureHandlerExceptionResolvers(List) to
|
||||
* customize the list of exception resolvers.
|
||||
* To customize the list of exception resolvers, override {@link #configureHandlerExceptionResolvers(List)}.
|
||||
*/
|
||||
@Bean
|
||||
HandlerExceptionResolver handlerExceptionResolver() throws Exception {
|
||||
|
|
@ -461,10 +439,10 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
|||
}
|
||||
|
||||
/**
|
||||
* Override this method to configure the list of {@link HandlerExceptionResolver}s to use for handling
|
||||
* unresolved controller exceptions. If any exception resolvers are added through this method, default
|
||||
* exception resolvers are not added automatically. For the list of exception resolvers added by
|
||||
* default see {@link #addDefaultHandlerExceptionResolvers(List)}.
|
||||
* Override this method to configure the list of {@link HandlerExceptionResolver}s to use.
|
||||
* Adding resolvers to the list turns off the default resolvers that would otherwise be registered by default.
|
||||
* Also see {@link #addDefaultHandlerExceptionResolvers(List)} that can be used to add the default exception resolvers.
|
||||
* @param exceptionResolvers a list to add exception resolvers to; initially an empty list.
|
||||
*/
|
||||
protected void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||
}
|
||||
|
|
@ -487,5 +465,13 @@ public abstract class WebMvcConfigurationSupport implements ApplicationContextAw
|
|||
exceptionResolvers.add(new ResponseStatusExceptionResolver());
|
||||
exceptionResolvers.add(new DefaultHandlerExceptionResolver());
|
||||
}
|
||||
|
||||
private final static class EmptyHandlerMapping extends AbstractHandlerMapping {
|
||||
|
||||
@Override
|
||||
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,23 +24,21 @@ 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 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
|
||||
import com.sun.corba.se.impl.presentation.rmi.ExceptionHandler;
|
||||
|
||||
/**
|
||||
* Defines configuration callback methods for customizing the default Spring MVC configuration enabled through the
|
||||
* use of @{@link EnableWebMvc}.
|
||||
* Defines configuration callback methods for customizing the default Spring MVC code-based configuration enabled
|
||||
* through @{@link EnableWebMvc}.
|
||||
*
|
||||
* <p>Classes annotated with @{@link EnableWebMvc} can implement this interface in order to be called back and
|
||||
* given a chance to customize the default configuration. The most convenient way to implement this interface is
|
||||
* by extending from {@link WebMvcConfigurerAdapter}, which provides empty method implementations and allows
|
||||
* overriding only the callback methods you're interested in.
|
||||
* given a chance to customize the default configuration. The most convenient way to implement this interface
|
||||
* is to extend {@link WebMvcConfigurerAdapter}, which provides empty method implementations.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Keith Donald
|
||||
|
|
@ -56,9 +54,9 @@ public interface WebMvcConfigurer {
|
|||
|
||||
/**
|
||||
* Configure the list of {@link HttpMessageConverter}s to use when resolving method arguments or handling
|
||||
* return values in @{@link RequestMapping} and @{@link ExceptionHandler} methods.
|
||||
* Specifying custom converters overrides the converters registered by default.
|
||||
* @param converters a list to add message converters to
|
||||
* return values in @{@link RequestMapping} and @{@link ExceptionHandler} methods.
|
||||
* Adding converters to the list turns off the default converters that would otherwise be registered by default.
|
||||
* @param converters a list to add message converters to; initially an empty list.
|
||||
*/
|
||||
void configureMessageConverters(List<HttpMessageConverter<?>> converters);
|
||||
|
||||
|
|
@ -71,58 +69,56 @@ public interface WebMvcConfigurer {
|
|||
|
||||
/**
|
||||
* Add custom {@link HandlerMethodArgumentResolver}s to use in addition to the ones registered by default.
|
||||
* <p>Generally custom argument resolvers are invoked first. However this excludes default argument resolvers that
|
||||
* rely on the presence of annotations (e.g. {@code @RequestParameter}, {@code @PathVariable}, etc.). Those
|
||||
* argument resolvers are not customizable without configuring RequestMappingHandlerAdapter directly.
|
||||
* @param argumentResolvers the list of custom converters, initially empty
|
||||
* <p>Custom argument resolvers are invoked before built-in resolvers except for those that rely on the presence
|
||||
* of annotations (e.g. {@code @RequestParameter}, {@code @PathVariable}, etc.). The latter can be customized
|
||||
* by configuring the {@link RequestMappingHandlerAdapter} directly.
|
||||
* @param argumentResolvers the list of custom converters; initially an empty list.
|
||||
*/
|
||||
void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers);
|
||||
|
||||
/**
|
||||
* Add custom {@link HandlerMethodReturnValueHandler}s to in addition to the ones registered by default.
|
||||
* <p>Generally custom return value handlers are invoked first. However this excludes default return value handlers
|
||||
* that rely on the presence of annotations (e.g. {@code @ResponseBody}, {@code @ModelAttribute}, etc.). Those
|
||||
* handlers are not customizable without configuring RequestMappingHandlerAdapter directly.
|
||||
* @param returnValueHandlers the list of custom handlers, initially empty
|
||||
* Add custom {@link HandlerMethodReturnValueHandler}s in addition to the ones registered by default.
|
||||
* <p>Custom return value handlers are invoked before built-in ones except for those that rely on the presence
|
||||
* of annotations (e.g. {@code @ResponseBody}, {@code @ModelAttribute}, etc.). The latter can be customized
|
||||
* by configuring the {@link RequestMappingHandlerAdapter} directly.
|
||||
* @param returnValueHandlers the list of custom handlers; initially an empty list.
|
||||
*/
|
||||
void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers);
|
||||
|
||||
/**
|
||||
* Configure the list of {@link HandlerExceptionResolver}s to use for handling unresolved controller exceptions.
|
||||
* Specifying exception resolvers overrides the ones registered by default.
|
||||
* @param exceptionResolvers a list to add exception resolvers to
|
||||
* Adding resolvers to the list turns off the default resolvers that would otherwise be registered by default.
|
||||
* @param exceptionResolvers a list to add exception resolvers to; initially an empty list.
|
||||
*/
|
||||
void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers);
|
||||
|
||||
/**
|
||||
* Configure the Spring MVC interceptors to use. Interceptors allow requests to be pre- and post-processed
|
||||
* before and after controller invocation. They can be registered to apply to all requests or be limited
|
||||
* to a set of path patterns.
|
||||
* @see InterceptorConfigurer
|
||||
* Add Spring MVC lifecycle interceptors for pre- and post-processing of controller method invocations.
|
||||
* Interceptors can be registered to apply to all requests or to a set of URL path patterns.
|
||||
* @see InterceptorRegistry
|
||||
*/
|
||||
void configureInterceptors(InterceptorConfigurer configurer);
|
||||
void addInterceptors(InterceptorRegistry registry);
|
||||
|
||||
/**
|
||||
* Configure 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.
|
||||
* @see ViewControllerConfigurer
|
||||
* Add view controllers to create a direct mapping between a URL path and view name. This is useful when
|
||||
* you just want to forward the request to a view such as a JSP without the need for controller logic.
|
||||
* @see ViewControllerRegistry
|
||||
*/
|
||||
void configureViewControllers(ViewControllerConfigurer configurer);
|
||||
void addViewControllers(ViewControllerRegistry registry);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @see ResourceConfigurer
|
||||
* Add resource handlers to use to serve static resources such as images, js, and, css files through
|
||||
* the Spring MVC {@link DispatcherServlet} including the setting of 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.
|
||||
* @see ResourceHandlerRegistry
|
||||
*/
|
||||
void configureResourceHandling(ResourceConfigurer configurer);
|
||||
void addResourceHandlers(ResourceHandlerRegistry registry);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* Configure a handler for delegating unhandled requests by forwarding to the Servlet container's "default"
|
||||
* servlet. The use case for this is when the {@link DispatcherServlet} is mapped to "/" thus overriding
|
||||
* the Servlet container's default handling of static resources.
|
||||
* @see DefaultServletHandlerConfigurer
|
||||
*/
|
||||
void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer);
|
||||
|
|
|
|||
|
|
@ -26,8 +26,7 @@ import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
|||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
|
||||
/**
|
||||
* An abstract class with empty method implementations of {@link WebMvcConfigurer}.
|
||||
* Subclasses can override only the methods they need.
|
||||
* An convenient base class with empty method implementations of {@link WebMvcConfigurer}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 3.1
|
||||
|
|
@ -81,21 +80,21 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
|
|||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void configureInterceptors(InterceptorConfigurer configurer) {
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void configureViewControllers(ViewControllerConfigurer configurer) {
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>This implementation is empty.
|
||||
*/
|
||||
public void configureResourceHandling(ResourceConfigurer configurer) {
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -74,21 +74,21 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer {
|
|||
}
|
||||
}
|
||||
|
||||
public void configureInterceptors(InterceptorConfigurer configurer) {
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
delegate.configureInterceptors(configurer);
|
||||
delegate.addInterceptors(registry);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureViewControllers(ViewControllerConfigurer configurer) {
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
delegate.configureViewControllers(configurer);
|
||||
delegate.addViewControllers(registry);
|
||||
}
|
||||
}
|
||||
|
||||
public void configureResourceHandling(ResourceConfigurer configurer) {
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
for (WebMvcConfigurer delegate : delegates) {
|
||||
delegate.configureResourceHandling(configurer);
|
||||
delegate.addResourceHandlers(registry);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ public class AnnotationDrivenBeanDefinitionParserTests {
|
|||
loadBeanDefinitions("mvc-config-message-codes-resolver.xml");
|
||||
RequestMappingHandlerAdapter adapter = appContext.getBean(RequestMappingHandlerAdapter.class);
|
||||
assertNotNull(adapter);
|
||||
Object initializer = new DirectFieldAccessor(adapter).getPropertyValue("webBindingInitializer");
|
||||
Object initializer = adapter.getWebBindingInitializer();
|
||||
assertNotNull(initializer);
|
||||
MessageCodesResolver resolver = ((ConfigurableWebBindingInitializer) initializer).getMessageCodesResolver();
|
||||
assertNotNull(resolver);
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ 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 static org.junit.Assert.assertNull;
|
||||
|
||||
import javax.servlet.RequestDispatcher;
|
||||
|
||||
|
|
@ -53,13 +53,14 @@ public class DefaultServletHandlerConfigurerTests {
|
|||
|
||||
@Test
|
||||
public void notEnabled() {
|
||||
assertTrue(configurer.getHandlerMapping().getUrlMap().isEmpty());
|
||||
assertNull(configurer.getHandlerMapping());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enable() throws Exception {
|
||||
configurer.enable();
|
||||
SimpleUrlHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
||||
SimpleUrlHandlerMapping getHandlerMapping = getHandlerMapping();
|
||||
SimpleUrlHandlerMapping handlerMapping = getHandlerMapping;
|
||||
DefaultServletHttpRequestHandler handler = (DefaultServletHttpRequestHandler) handlerMapping.getUrlMap().get("/**");
|
||||
|
||||
assertNotNull(handler);
|
||||
|
|
@ -75,7 +76,7 @@ public class DefaultServletHandlerConfigurerTests {
|
|||
@Test
|
||||
public void enableWithServletName() throws Exception {
|
||||
configurer.enable("defaultServlet");
|
||||
SimpleUrlHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
||||
SimpleUrlHandlerMapping handlerMapping = getHandlerMapping();
|
||||
DefaultServletHttpRequestHandler handler = (DefaultServletHttpRequestHandler) handlerMapping.getUrlMap().get("/**");
|
||||
|
||||
assertNotNull(handler);
|
||||
|
|
@ -99,4 +100,8 @@ public class DefaultServletHandlerConfigurerTests {
|
|||
}
|
||||
}
|
||||
|
||||
private SimpleUrlHandlerMapping getHandlerMapping() {
|
||||
return (SimpleUrlHandlerMapping) configurer.getHandlerMapping();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,11 +18,9 @@ package org.springframework.web.servlet.config.annotation;
|
|||
|
||||
import static org.easymock.EasyMock.capture;
|
||||
import static org.easymock.EasyMock.expect;
|
||||
import static org.easymock.EasyMock.isA;
|
||||
import static org.easymock.EasyMock.replay;
|
||||
import static org.easymock.EasyMock.verify;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
|
@ -30,8 +28,6 @@ import java.util.ArrayList;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.easymock.Capture;
|
||||
import org.easymock.EasyMock;
|
||||
import org.junit.Before;
|
||||
|
|
@ -39,29 +35,23 @@ import org.junit.Test;
|
|||
import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
||||
import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite;
|
||||
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||
|
||||
/**
|
||||
* A test fixture for WebMvcConfiguration tests.
|
||||
* A test fixture for {@link DelegatingWebMvcConfiguration} tests.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class WebMvcConfigurationTests {
|
||||
public class DelegatingWebMvcConfigurationTests {
|
||||
|
||||
private DelegatingWebMvcConfiguration mvcConfiguration;
|
||||
|
||||
|
|
@ -74,7 +64,7 @@ public class WebMvcConfigurationTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void annotationHandlerAdapter() throws Exception {
|
||||
public void requestMappingHandlerAdapter() throws Exception {
|
||||
Capture<List<HttpMessageConverter<?>>> converters = new Capture<List<HttpMessageConverter<?>>>();
|
||||
Capture<FormattingConversionService> conversionService = new Capture<FormattingConversionService>();
|
||||
Capture<List<HandlerMethodArgumentResolver>> resolvers = new Capture<List<HandlerMethodArgumentResolver>>();
|
||||
|
|
@ -96,7 +86,6 @@ public class WebMvcConfigurationTests {
|
|||
|
||||
assertEquals(0, resolvers.getValue().size());
|
||||
assertEquals(0, handlers.getValue().size());
|
||||
assertTrue(converters.getValue().size() > 0);
|
||||
assertEquals(converters.getValue(), adapter.getMessageConverters());
|
||||
|
||||
verify(configurer);
|
||||
|
|
@ -104,9 +93,6 @@ public class WebMvcConfigurationTests {
|
|||
|
||||
@Test
|
||||
public void configureMessageConverters() {
|
||||
RequestMappingHandlerAdapter adapter = mvcConfiguration.requestMappingHandlerAdapter();
|
||||
assertTrue("There should be at least two default converters ", adapter.getMessageConverters().size() > 1);
|
||||
|
||||
List<WebMvcConfigurer> configurers = new ArrayList<WebMvcConfigurer>();
|
||||
configurers.add(new WebMvcConfigurerAdapter() {
|
||||
@Override
|
||||
|
|
@ -117,7 +103,7 @@ public class WebMvcConfigurationTests {
|
|||
mvcConfiguration = new DelegatingWebMvcConfiguration();
|
||||
mvcConfiguration.setConfigurers(configurers);
|
||||
|
||||
adapter = mvcConfiguration.requestMappingHandlerAdapter();
|
||||
RequestMappingHandlerAdapter adapter = mvcConfiguration.requestMappingHandlerAdapter();
|
||||
assertEquals("Only one custom converter should be registered", 1, adapter.getMessageConverters().size());
|
||||
}
|
||||
|
||||
|
|
@ -132,17 +118,6 @@ public class WebMvcConfigurationTests {
|
|||
verify(configurer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configureValidator() {
|
||||
expect(configurer.getValidator()).andReturn(null);
|
||||
replay(configurer);
|
||||
|
||||
mvcConfiguration.setConfigurers(Arrays.asList(configurer));
|
||||
mvcConfiguration.mvcValidator();
|
||||
|
||||
verify(configurer);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlerExceptionResolver() throws Exception {
|
||||
Capture<List<HttpMessageConverter<?>>> converters = new Capture<List<HttpMessageConverter<?>>>();
|
||||
|
|
@ -166,11 +141,6 @@ public class WebMvcConfigurationTests {
|
|||
|
||||
@Test
|
||||
public void configureExceptionResolvers() throws Exception {
|
||||
HandlerExceptionResolverComposite composite;
|
||||
|
||||
composite = (HandlerExceptionResolverComposite) mvcConfiguration.handlerExceptionResolver();
|
||||
assertTrue("Expected more than one exception resolver by default", composite.getExceptionResolvers().size() > 1);
|
||||
|
||||
List<WebMvcConfigurer> configurers = new ArrayList<WebMvcConfigurer>();
|
||||
configurers.add(new WebMvcConfigurerAdapter() {
|
||||
@Override
|
||||
|
|
@ -180,32 +150,9 @@ public class WebMvcConfigurationTests {
|
|||
});
|
||||
mvcConfiguration.setConfigurers(configurers);
|
||||
|
||||
composite = (HandlerExceptionResolverComposite) mvcConfiguration.handlerExceptionResolver();
|
||||
HandlerExceptionResolverComposite composite =
|
||||
(HandlerExceptionResolverComposite) mvcConfiguration.handlerExceptionResolver();
|
||||
assertEquals("Only one custom converter is expected", 1, composite.getExceptionResolvers().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void configureInterceptors() throws Exception {
|
||||
HttpServletRequest request = new MockHttpServletRequest("GET", "/");
|
||||
|
||||
StaticWebApplicationContext context = new StaticWebApplicationContext();
|
||||
context.registerSingleton("controller", TestHandler.class);
|
||||
|
||||
RequestMappingHandlerMapping hm = mvcConfiguration.requestMappingHandlerMapping();
|
||||
hm.setApplicationContext(context);
|
||||
HandlerExecutionChain chain = hm.getHandler(request);
|
||||
assertNotNull("No chain returned", chain);
|
||||
assertNotNull("Expected at least one default converter", chain.getInterceptors());
|
||||
}
|
||||
|
||||
@Controller
|
||||
private static class TestHandler {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@RequestMapping("/")
|
||||
public void handle() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -40,14 +40,14 @@ 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
|
||||
* Test fixture with a {@link InterceptorRegistry}, two {@link HandlerInterceptor}s and two
|
||||
* {@link WebRequestInterceptor}s.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class InterceptorConfigurerTests {
|
||||
public class InterceptorRegistryTests {
|
||||
|
||||
private InterceptorConfigurer configurer;
|
||||
private InterceptorRegistry registry;
|
||||
|
||||
private final HandlerInterceptor interceptor1 = new LocaleChangeInterceptor();
|
||||
|
||||
|
|
@ -63,54 +63,50 @@ public class InterceptorConfigurerTests {
|
|||
|
||||
@Before
|
||||
public void setUp() {
|
||||
configurer = new InterceptorConfigurer();
|
||||
registry = new InterceptorRegistry();
|
||||
webRequestInterceptor1 = new TestWebRequestInterceptor();
|
||||
webRequestInterceptor2 = new TestWebRequestInterceptor();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addInterceptor() {
|
||||
configurer.addInterceptor(interceptor1);
|
||||
registry.addInterceptor(interceptor1);
|
||||
List<HandlerInterceptor> interceptors = getInterceptorsForPath(null);
|
||||
|
||||
assertEquals(Arrays.asList(interceptor1), interceptors);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addInterceptors() {
|
||||
configurer.addInterceptors(interceptor1, interceptor2);
|
||||
public void addTwoInterceptors() {
|
||||
registry.addInterceptor(interceptor1);
|
||||
registry.addInterceptor(interceptor2);
|
||||
List<HandlerInterceptor> interceptors = getInterceptorsForPath(null);
|
||||
|
||||
assertEquals(Arrays.asList(interceptor1, interceptor2), interceptors);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mapInterceptor() {
|
||||
configurer.mapInterceptor(new String[] {"/path1"}, interceptor1);
|
||||
configurer.mapInterceptor(new String[] {"/path2"}, interceptor2);
|
||||
|
||||
public void addInterceptorsWithUrlPatterns() {
|
||||
registry.addInterceptor(interceptor1).addPathPatterns("/path1");
|
||||
registry.addInterceptor(interceptor2).addPathPatterns("/path2");
|
||||
|
||||
assertEquals(Arrays.asList(interceptor1), getInterceptorsForPath("/path1"));
|
||||
assertEquals(Arrays.asList(interceptor2), getInterceptorsForPath("/path2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mapInterceptors() {
|
||||
configurer.mapInterceptors(new String[] {"/path1"}, interceptor1, interceptor2);
|
||||
|
||||
assertEquals(Arrays.asList(interceptor1, interceptor2), getInterceptorsForPath("/path1"));
|
||||
assertEquals(Arrays.asList(), getInterceptorsForPath("/path2"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addWebRequestInterceptor() throws Exception {
|
||||
configurer.addInterceptor(webRequestInterceptor1);
|
||||
registry.addWebRequestInterceptor(webRequestInterceptor1);
|
||||
List<HandlerInterceptor> interceptors = getInterceptorsForPath(null);
|
||||
|
||||
|
||||
assertEquals(1, interceptors.size());
|
||||
verifyAdaptedInterceptor(interceptors.get(0), webRequestInterceptor1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addWebRequestInterceptors() throws Exception {
|
||||
configurer.addInterceptors(webRequestInterceptor1, webRequestInterceptor2);
|
||||
registry.addWebRequestInterceptor(webRequestInterceptor1);
|
||||
registry.addWebRequestInterceptor(webRequestInterceptor2);
|
||||
List<HandlerInterceptor> interceptors = getInterceptorsForPath(null);
|
||||
|
||||
assertEquals(2, interceptors.size());
|
||||
|
|
@ -119,9 +115,9 @@ public class InterceptorConfigurerTests {
|
|||
}
|
||||
|
||||
@Test
|
||||
public void mapWebRequestInterceptor() throws Exception {
|
||||
configurer.mapInterceptor(new String[] {"/path1"}, webRequestInterceptor1);
|
||||
configurer.mapInterceptor(new String[] {"/path2"}, webRequestInterceptor2);
|
||||
public void addWebRequestInterceptorsWithUrlPatterns() throws Exception {
|
||||
registry.addWebRequestInterceptor(webRequestInterceptor1).addPathPatterns("/path1");
|
||||
registry.addWebRequestInterceptor(webRequestInterceptor2).addPathPatterns("/path2");
|
||||
|
||||
List<HandlerInterceptor> interceptors = getInterceptorsForPath("/path1");
|
||||
assertEquals(1, interceptors.size());
|
||||
|
|
@ -132,22 +128,10 @@ public class InterceptorConfigurerTests {
|
|||
verifyAdaptedInterceptor(interceptors.get(0), webRequestInterceptor2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mapWebRequestInterceptor2() throws Exception {
|
||||
configurer.mapInterceptors(new String[] {"/path1"}, webRequestInterceptor1, webRequestInterceptor2);
|
||||
|
||||
List<HandlerInterceptor> interceptors = getInterceptorsForPath("/path1");
|
||||
assertEquals(2, interceptors.size());
|
||||
verifyAdaptedInterceptor(interceptors.get(0), webRequestInterceptor1);
|
||||
verifyAdaptedInterceptor(interceptors.get(1), webRequestInterceptor2);
|
||||
|
||||
assertEquals(0, getInterceptorsForPath("/path2").size());
|
||||
}
|
||||
|
||||
private List<HandlerInterceptor> getInterceptorsForPath(String lookupPath) {
|
||||
PathMatcher pathMatcher = new AntPathMatcher();
|
||||
List<HandlerInterceptor> result = new ArrayList<HandlerInterceptor>();
|
||||
for (Object i : configurer.getInterceptors()) {
|
||||
for (Object i : registry.getInterceptors()) {
|
||||
if (i instanceof MappedInterceptor) {
|
||||
MappedInterceptor mappedInterceptor = (MappedInterceptor) i;
|
||||
if (mappedInterceptor.matches(lookupPath, pathMatcher)) {
|
||||
|
|
@ -17,7 +17,7 @@
|
|||
package org.springframework.web.servlet.config.annotation;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
|
@ -26,32 +26,34 @@ 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.handler.SimpleUrlHandlerMapping;
|
||||
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
|
||||
|
||||
/**
|
||||
* Test fixture with a {@link ResourceConfigurer}.
|
||||
* Test fixture with a {@link ResourceHandlerRegistry}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class ResourceConfigurerTests {
|
||||
public class ResourceHandlerRegistryTests {
|
||||
|
||||
private ResourceConfigurer configurer;
|
||||
private ResourceHandlerRegistry registry;
|
||||
|
||||
private ResourceHandlerRegistration registration;
|
||||
|
||||
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/");
|
||||
|
||||
registry = new ResourceHandlerRegistry(new GenericWebApplicationContext(), new MockServletContext());
|
||||
registration = registry.addResourceHandler("/resources/**");
|
||||
registration.addResourceLocations("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());
|
||||
public void noResourceHandlers() throws Exception {
|
||||
registry = new ResourceHandlerRegistry(new GenericWebApplicationContext(), new MockServletContext());
|
||||
assertNull(registry.getHandlerMapping());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -60,7 +62,7 @@ public class ResourceConfigurerTests {
|
|||
request.setMethod("GET");
|
||||
request.setAttribute(HandlerMapping.PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, "/testStylesheet.css");
|
||||
|
||||
ResourceHttpRequestHandler handler = getResourceHandler("/resources/**");
|
||||
ResourceHttpRequestHandler handler = getHandler("/resources/**");
|
||||
handler.handleRequest(request, response);
|
||||
|
||||
assertEquals("test stylesheet content", response.getContentAsString());
|
||||
|
|
@ -68,22 +70,23 @@ public class ResourceConfigurerTests {
|
|||
|
||||
@Test
|
||||
public void cachePeriod() {
|
||||
assertEquals(-1, getResourceHandler("/resources/**").getCacheSeconds());
|
||||
assertEquals(-1, getHandler("/resources/**").getCacheSeconds());
|
||||
|
||||
configurer.setCachePeriod(0);
|
||||
assertEquals(0, getResourceHandler("/resources/**").getCacheSeconds());
|
||||
registration.setCachePeriod(0);
|
||||
assertEquals(0, getHandler("/resources/**").getCacheSeconds());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void order() {
|
||||
assertEquals(Integer.MAX_VALUE -1, configurer.getHandlerMapping().getOrder());
|
||||
assertEquals(Integer.MAX_VALUE -1, registry.getHandlerMapping().getOrder());
|
||||
|
||||
configurer.setOrder(0);
|
||||
assertEquals(0, configurer.getHandlerMapping().getOrder());
|
||||
registry.setOrder(0);
|
||||
assertEquals(0, registry.getHandlerMapping().getOrder());
|
||||
}
|
||||
|
||||
private ResourceHttpRequestHandler getResourceHandler(String pathPattern) {
|
||||
return (ResourceHttpRequestHandler) configurer.getHandlerMapping().getUrlMap().get(pathPattern);
|
||||
private ResourceHttpRequestHandler getHandler(String pathPattern) {
|
||||
SimpleUrlHandlerMapping handlerMapping = (SimpleUrlHandlerMapping) registry.getHandlerMapping();
|
||||
return (ResourceHttpRequestHandler) handlerMapping.getUrlMap().get(pathPattern);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -16,7 +16,9 @@
|
|||
|
||||
package org.springframework.web.servlet.config.annotation;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertNull;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
|
|
@ -26,50 +28,55 @@ import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
|
|||
import org.springframework.web.servlet.mvc.ParameterizableViewController;
|
||||
|
||||
/**
|
||||
* Test fixture with a {@link ViewControllerConfigurer}.
|
||||
* Test fixture with a {@link ViewControllerRegistry}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class ViewControllerConfigurerTests {
|
||||
public class ViewControllerRegistryTests {
|
||||
|
||||
private ViewControllerConfigurer configurer;
|
||||
private ViewControllerRegistry registry;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
configurer = new ViewControllerConfigurer();
|
||||
registry = new ViewControllerRegistry();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noMappings() throws Exception {
|
||||
Map<String, ?> urlMap = configurer.getHandlerMapping().getUrlMap();
|
||||
assertTrue(urlMap.isEmpty());
|
||||
public void noViewControllers() throws Exception {
|
||||
assertNull(registry.getHandlerMapping());
|
||||
}
|
||||
|
||||
@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();
|
||||
public void addViewController() {
|
||||
registry.addViewController("/path");
|
||||
Map<String, ?> urlMap = getHandlerMapping().getUrlMap();
|
||||
ParameterizableViewController controller = (ParameterizableViewController) urlMap.get("/path");
|
||||
assertNotNull(controller);
|
||||
assertNull(controller.getViewName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addViewControllerWithViewName() {
|
||||
registry.addViewController("/path").setViewName("viewName");
|
||||
Map<String, ?> urlMap = getHandlerMapping().getUrlMap();
|
||||
ParameterizableViewController controller = (ParameterizableViewController) urlMap.get("/path");
|
||||
assertNotNull(controller);
|
||||
assertEquals("viewName", controller.getViewName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void order() {
|
||||
SimpleUrlHandlerMapping handlerMapping = configurer.getHandlerMapping();
|
||||
registry.addViewController("/path");
|
||||
SimpleUrlHandlerMapping handlerMapping = getHandlerMapping();
|
||||
assertEquals(1, handlerMapping.getOrder());
|
||||
|
||||
configurer.setOrder(2);
|
||||
handlerMapping = configurer.getHandlerMapping();
|
||||
registry.setOrder(2);
|
||||
handlerMapping = getHandlerMapping();
|
||||
assertEquals(2, handlerMapping.getOrder());
|
||||
}
|
||||
|
||||
private SimpleUrlHandlerMapping getHandlerMapping() {
|
||||
return (SimpleUrlHandlerMapping) registry.getHandlerMapping();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,315 @@
|
|||
/*
|
||||
* 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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.DirectFieldAccessor;
|
||||
import org.springframework.beans.TestBean;
|
||||
import org.springframework.core.convert.ConversionService;
|
||||
import org.springframework.core.convert.converter.Converter;
|
||||
import org.springframework.core.io.FileSystemResourceLoader;
|
||||
import org.springframework.format.FormatterRegistry;
|
||||
import org.springframework.format.support.FormattingConversionService;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockServletContext;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.validation.BeanPropertyBindingResult;
|
||||
import org.springframework.validation.Errors;
|
||||
import org.springframework.validation.Validator;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||
import org.springframework.web.method.annotation.support.ModelAttributeMethodProcessor;
|
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler;
|
||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
||||
import org.springframework.web.servlet.handler.AbstractHandlerMapping;
|
||||
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.SimpleMappingExceptionResolver;
|
||||
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||
import org.springframework.web.servlet.mvc.method.annotation.support.DefaultMethodReturnValueHandler;
|
||||
|
||||
/**
|
||||
* A test fixture for {@link WebMvcConfigurationSupport}.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class WebMvcConfigurationSupportTests {
|
||||
|
||||
private TestWebMvcConfiguration mvcConfiguration;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
mvcConfiguration = new TestWebMvcConfiguration();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestMappingHandlerMapping() throws Exception {
|
||||
StaticWebApplicationContext cxt = new StaticWebApplicationContext();
|
||||
cxt.registerSingleton("controller", TestController.class);
|
||||
|
||||
RequestMappingHandlerMapping handlerMapping = mvcConfiguration.requestMappingHandlerMapping();
|
||||
assertEquals(0, handlerMapping.getOrder());
|
||||
|
||||
handlerMapping.setApplicationContext(cxt);
|
||||
HandlerExecutionChain chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/"));
|
||||
assertNotNull(chain.getInterceptors());
|
||||
assertEquals(ConversionServiceExposingInterceptor.class, chain.getInterceptors()[0].getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyViewControllerHandlerMapping() {
|
||||
AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping) mvcConfiguration.viewControllerHandlerMapping();
|
||||
assertNotNull(handlerMapping);
|
||||
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder());
|
||||
assertTrue(handlerMapping.getClass().getName().endsWith("EmptyHandlerMapping"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beanNameHandlerMapping() throws Exception {
|
||||
StaticWebApplicationContext cxt = new StaticWebApplicationContext();
|
||||
cxt.registerSingleton("/controller", TestController.class);
|
||||
|
||||
HttpServletRequest request = new MockHttpServletRequest("GET", "/controller");
|
||||
|
||||
BeanNameUrlHandlerMapping handlerMapping = mvcConfiguration.beanNameHandlerMapping();
|
||||
assertEquals(2, handlerMapping.getOrder());
|
||||
|
||||
handlerMapping.setApplicationContext(cxt);
|
||||
HandlerExecutionChain chain = handlerMapping.getHandler(request);
|
||||
assertNotNull(chain.getInterceptors());
|
||||
assertEquals(2, chain.getInterceptors().length);
|
||||
assertEquals(ConversionServiceExposingInterceptor.class, chain.getInterceptors()[1].getClass());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyResourceHandlerMapping() {
|
||||
mvcConfiguration.setApplicationContext(new StaticWebApplicationContext());
|
||||
AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping) mvcConfiguration.resourceHandlerMapping();
|
||||
assertNotNull(handlerMapping);
|
||||
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder());
|
||||
assertTrue(handlerMapping.getClass().getName().endsWith("EmptyHandlerMapping"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void emptyDefaultServletHandlerMapping() {
|
||||
mvcConfiguration.setServletContext(new MockServletContext());
|
||||
AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping) mvcConfiguration.defaultServletHandlerMapping();
|
||||
assertNotNull(handlerMapping);
|
||||
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder());
|
||||
assertTrue(handlerMapping.getClass().getName().endsWith("EmptyHandlerMapping"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestMappingHandlerAdapter() throws Exception {
|
||||
RequestMappingHandlerAdapter adapter = mvcConfiguration.requestMappingHandlerAdapter();
|
||||
|
||||
List<HttpMessageConverter<?>> expectedConverters = new ArrayList<HttpMessageConverter<?>>();
|
||||
mvcConfiguration.addDefaultHttpMessageConverters(expectedConverters);
|
||||
assertEquals(expectedConverters.size(), adapter.getMessageConverters().size());
|
||||
|
||||
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer();
|
||||
assertNotNull(initializer);
|
||||
|
||||
ConversionService conversionService = initializer.getConversionService();
|
||||
assertNotNull(conversionService);
|
||||
assertTrue(conversionService instanceof FormattingConversionService);
|
||||
|
||||
Validator validator = initializer.getValidator();
|
||||
assertNotNull(validator);
|
||||
assertTrue(validator instanceof LocalValidatorFactoryBean);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handlerExceptionResolver() throws Exception {
|
||||
HandlerExceptionResolverComposite compositeResolver =
|
||||
(HandlerExceptionResolverComposite) mvcConfiguration.handlerExceptionResolver();
|
||||
|
||||
assertEquals(0, compositeResolver.getOrder());
|
||||
|
||||
List<HandlerExceptionResolver> expectedResolvers = new ArrayList<HandlerExceptionResolver>();
|
||||
mvcConfiguration.addDefaultHandlerExceptionResolvers(expectedResolvers);
|
||||
assertEquals(expectedResolvers.size(), compositeResolver.getExceptionResolvers().size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void webMvcConfigurerExtensionHooks() throws Exception {
|
||||
|
||||
StaticWebApplicationContext appCxt = new StaticWebApplicationContext();
|
||||
appCxt.setServletContext(new MockServletContext(new FileSystemResourceLoader()));
|
||||
appCxt.registerSingleton("controller", TestController.class);
|
||||
|
||||
WebConfig webConfig = new WebConfig();
|
||||
webConfig.setApplicationContext(appCxt);
|
||||
webConfig.setServletContext(appCxt.getServletContext());
|
||||
|
||||
String actual = webConfig.mvcConversionService().convert(new TestBean(), String.class);
|
||||
assertEquals("converted", actual);
|
||||
|
||||
RequestMappingHandlerAdapter adapter = webConfig.requestMappingHandlerAdapter();
|
||||
assertEquals(1, adapter.getMessageConverters().size());
|
||||
|
||||
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer();
|
||||
assertNotNull(initializer);
|
||||
|
||||
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(null, "");
|
||||
initializer.getValidator().validate(null, bindingResult);
|
||||
assertEquals("invalid", bindingResult.getAllErrors().get(0).getCode());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<HandlerMethodArgumentResolver> argResolvers= (List<HandlerMethodArgumentResolver>)
|
||||
new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers");
|
||||
assertEquals(1, argResolvers.size());
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<HandlerMethodReturnValueHandler> handlers = (List<HandlerMethodReturnValueHandler>)
|
||||
new DirectFieldAccessor(adapter).getPropertyValue("customReturnValueHandlers");
|
||||
assertEquals(1, handlers.size());
|
||||
|
||||
HandlerExceptionResolverComposite composite = (HandlerExceptionResolverComposite) webConfig.handlerExceptionResolver();
|
||||
assertEquals(1, composite.getExceptionResolvers().size());
|
||||
|
||||
RequestMappingHandlerMapping rmHandlerMapping = webConfig.requestMappingHandlerMapping();
|
||||
rmHandlerMapping.setApplicationContext(appCxt);
|
||||
HandlerExecutionChain chain = rmHandlerMapping.getHandler(new MockHttpServletRequest("GET", "/"));
|
||||
assertNotNull(chain.getInterceptors());
|
||||
assertEquals(2, chain.getInterceptors().length);
|
||||
assertEquals(LocaleChangeInterceptor.class, chain.getInterceptors()[0].getClass());
|
||||
assertEquals(ConversionServiceExposingInterceptor.class, chain.getInterceptors()[1].getClass());
|
||||
|
||||
AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping) webConfig.viewControllerHandlerMapping();
|
||||
handlerMapping.setApplicationContext(appCxt);
|
||||
assertNotNull(handlerMapping);
|
||||
assertEquals(1, handlerMapping.getOrder());
|
||||
HandlerExecutionChain handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/path"));
|
||||
assertNotNull(handler.getHandler());
|
||||
|
||||
handlerMapping = (AbstractHandlerMapping) webConfig.resourceHandlerMapping();
|
||||
handlerMapping.setApplicationContext(appCxt);
|
||||
assertNotNull(handlerMapping);
|
||||
assertEquals(Integer.MAX_VALUE-1, handlerMapping.getOrder());
|
||||
handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/resources/foo.gif"));
|
||||
assertNotNull(handler.getHandler());
|
||||
|
||||
handlerMapping = (AbstractHandlerMapping) webConfig.defaultServletHandlerMapping();
|
||||
handlerMapping.setApplicationContext(appCxt);
|
||||
assertNotNull(handlerMapping);
|
||||
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder());
|
||||
handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/anyPath"));
|
||||
assertNotNull(handler.getHandler());
|
||||
}
|
||||
|
||||
@Controller
|
||||
private static class TestController {
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@RequestMapping("/")
|
||||
public void handle() {
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestWebMvcConfiguration extends WebMvcConfigurationSupport {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The purpose of this class is to test that an implementation of a {@link WebMvcConfigurer}
|
||||
* can also apply customizations by extension from {@link WebMvcConfigurationSupport}.
|
||||
*/
|
||||
private class WebConfig extends WebMvcConfigurationSupport implements WebMvcConfigurer {
|
||||
|
||||
@Override
|
||||
public void addFormatters(FormatterRegistry registry) {
|
||||
registry.addConverter(new Converter<TestBean, String>() {
|
||||
public String convert(TestBean source) {
|
||||
return "converted";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||
converters.add(new MappingJacksonHttpMessageConverter());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Validator getValidator() {
|
||||
return new Validator() {
|
||||
public void validate(Object target, Errors errors) {
|
||||
errors.reject("invalid");
|
||||
}
|
||||
public boolean supports(Class<?> clazz) {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
|
||||
argumentResolvers.add(new ModelAttributeMethodProcessor(true));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
|
||||
returnValueHandlers.add(new DefaultMethodReturnValueHandler());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
|
||||
exceptionResolvers.add(new SimpleMappingExceptionResolver());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInterceptors(InterceptorRegistry registry) {
|
||||
registry.addInterceptor(new LocaleChangeInterceptor());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addViewControllers(ViewControllerRegistry registry) {
|
||||
registry.addViewController("/path");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||
registry.addResourceHandler("/resources/**").addResourceLocations("src/test/java");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
|
||||
configurer.enable("default");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue