diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurer.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurer.java
index e9b713fc7ea..cb80e95c2f2 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurer.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurer.java
@@ -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.
- *
- *
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 urlMap = new HashMap();
+ urlMap.put("/**", handler);
+
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
handlerMapping.setOrder(Integer.MAX_VALUE);
- handlerMapping.setUrlMap(getUrlMap());
+ handlerMapping.setUrlMap(urlMap);
return handlerMapping;
}
- private Map getUrlMap() {
- Map urlMap = new HashMap();
- if (requestHandler != null) {
- urlMap.put("/**", requestHandler);
- }
- return urlMap ;
- }
-
}
\ No newline at end of file
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java
index 59bc12d4f7e..a459a12700f 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.java
@@ -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.
*
- * 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.
+ *
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
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java
index 92794b627c1..b6379fcb717 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/EnableWebMvc.java
@@ -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.
*
* @Configuration
* @EnableWebMvc
@@ -39,9 +38,9 @@ import org.springframework.web.servlet.DispatcherServlet;
* }
*
* 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.
*
* @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 ...
*
* }
*
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/InterceptorConfigurer.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/InterceptorConfigurer.java
deleted file mode 100644
index 3ce466121e1..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/InterceptorConfigurer.java
+++ /dev/null
@@ -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 interceptors = new ArrayList();
-
- /**
- * 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 getInterceptors() {
- return interceptors;
- }
-
-}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/InterceptorRegistration.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/InterceptorRegistration.java
new file mode 100644
index 00000000000..6ef77d2ef97
--- /dev/null
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/InterceptorRegistration.java
@@ -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 pathPatterns = new ArrayList();
+
+ /**
+ * 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);
+ }
+
+}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/InterceptorRegistry.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/InterceptorRegistry.java
new file mode 100644
index 00000000000..7988a67c702
--- /dev/null
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/InterceptorRegistry.java
@@ -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 registrations = new ArrayList();
+
+ /**
+ * 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 getInterceptors() {
+ List interceptors = new ArrayList();
+ for (InterceptorRegistration registration : registrations) {
+ interceptors.add(registration.getInterceptor());
+ }
+ return interceptors ;
+ }
+
+}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ResourceConfigurer.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ResourceConfigurer.java
deleted file mode 100644
index 576f91f457b..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ResourceConfigurer.java
+++ /dev/null
@@ -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.
- *
- * 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/**"}.
- *
- *
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.
- *
- *
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 pathPatterns = new ArrayList();
-
- private final List locations = new ArrayList();
-
- 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. 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.
- *
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 getUrlMap() {
- Map urlMap = new LinkedHashMap();
- 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;
- }
-
-}
\ No newline at end of file
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistration.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistration.java
new file mode 100644
index 00000000000..cbad096879b
--- /dev/null
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistration.java
@@ -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 locations = new ArrayList();
+
+ 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.
+ * 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;
+ }
+
+}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.java
new file mode 100644
index 00000000000..e95cc82aaca
--- /dev/null
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistry.java
@@ -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.
+ *
+ *
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/**"}).
+ *
+ *
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 registrations = new ArrayList();
+
+ 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 urlMap = new LinkedHashMap();
+ 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;
+ }
+
+}
\ No newline at end of file
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerConfigurer.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerConfigurer.java
deleted file mode 100644
index a5946b63c26..00000000000
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerConfigurer.java
+++ /dev/null
@@ -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 urlMap = new LinkedHashMap();
-
- 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;
- }
-
-}
\ No newline at end of file
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistration.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistration.java
new file mode 100644
index 00000000000..48700f905d7
--- /dev/null
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistration.java
@@ -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;
+ }
+
+}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistry.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistry.java
new file mode 100644
index 00000000000..55d3d457d05
--- /dev/null
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistry.java
@@ -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 registrations = new ArrayList();
+
+ 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 urlMap = new LinkedHashMap();
+ for (ViewControllerRegistration registration : registrations) {
+ urlMap.put(registration.getUrlPath(), registration.getViewController());
+ }
+
+ SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
+ handlerMapping.setOrder(order);
+ handlerMapping.setUrlMap(urlMap);
+ return handlerMapping;
+ }
+
+}
\ No newline at end of file
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java
index 2fe02419360..8da51d8aeb6 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupport.java
@@ -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).
*
- * 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.
+ *
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.
*
*
This class registers the following {@link HandlerMapping}s:
*
* {@link RequestMappingHandlerMapping} ordered at 0 for mapping requests to annotated controller methods.
- * {@link SimpleUrlHandlerMapping} ordered at 1 to map URL paths directly to view names.
+ * {@link HandlerMapping} ordered at 1 to map URL paths directly to view names.
* {@link BeanNameUrlHandlerMapping} ordered at 2 to map URL paths to controller bean names.
- * {@link SimpleUrlHandlerMapping} ordered at {@code Integer.MAX_VALUE-1} to serve static resource requests.
- * {@link SimpleUrlHandlerMapping} ordered at {@code Integer.MAX_VALUE} to forward requests to the default servlet.
+ * {@link HandlerMapping} ordered at {@code Integer.MAX_VALUE-1} to serve static resource requests.
+ * {@link HandlerMapping} ordered at {@code Integer.MAX_VALUE} to forward requests to the default servlet.
*
*
- * Registers {@link HandlerAdapter}s:
+ *
Registers these {@link HandlerAdapter}s:
*
- * {@link RequestMappingHandlerAdapter} for processing requests using annotated controller methods.
+ * {@link RequestMappingHandlerAdapter} for processing requests with annotated controller methods.
* {@link HttpRequestHandlerAdapter} for processing requests with {@link HttpRequestHandler}s.
* {@link SimpleControllerHandlerAdapter} for processing requests with interface-based {@link Controller}s.
*
@@ -107,7 +105,7 @@ import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolv
* {@link DefaultHandlerExceptionResolver} for resolving known Spring exception types
*
*
- * Registers the following other instances:
+ *
Registers these other instances:
*
* {@link FormattingConversionService} for use with annotated controller methods and the spring:eval JSP tag.
* {@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:
*
- * {@link #initWebBindingInitializer()} for configuring data binding globally.
* {@link #addArgumentResolvers(List)} for adding custom argument resolvers.
* {@link #addReturnValueHandlers(List)} for adding custom return value handlers.
* {@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 argumentResolvers = new ArrayList();
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}.
- * 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.
+ *
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 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}.
- * 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.
+ *
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 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> 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> 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> 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 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;
+ }
+ }
}
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java
index 8e1e9b2b3bd..665b9325df8 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurer.java
@@ -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}.
*
* 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> converters);
@@ -71,58 +69,56 @@ public interface WebMvcConfigurer {
/**
* Add custom {@link HandlerMethodArgumentResolver}s to use in addition to the ones registered by default.
- * 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
+ *
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 argumentResolvers);
/**
- * Add custom {@link HandlerMethodReturnValueHandler}s to in addition to the ones registered by default.
- * 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.
+ *
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 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 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);
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java
index d3ef44d8c51..6f941eca5af 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerAdapter.java
@@ -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}
* This implementation is empty.
*/
- public void configureInterceptors(InterceptorConfigurer configurer) {
+ public void addInterceptors(InterceptorRegistry registry) {
}
/**
* {@inheritDoc}
*
This implementation is empty.
*/
- public void configureViewControllers(ViewControllerConfigurer configurer) {
+ public void addViewControllers(ViewControllerRegistry registry) {
}
/**
* {@inheritDoc}
*
This implementation is empty.
*/
- public void configureResourceHandling(ResourceConfigurer configurer) {
+ public void addResourceHandlers(ResourceHandlerRegistry registry) {
}
/**
diff --git a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java
index 5a602174275..1c0e7494e9a 100644
--- a/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java
+++ b/org.springframework.web.servlet/src/main/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurerComposite.java
@@ -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);
}
}
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParserTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParserTests.java
index 72531cfa53e..c9c586240f7 100644
--- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParserTests.java
+++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/AnnotationDrivenBeanDefinitionParserTests.java
@@ -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);
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurerTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurerTests.java
index 874ef655d99..8d00d78dc90 100644
--- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurerTests.java
+++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/DefaultServletHandlerConfigurerTests.java
@@ -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();
+ }
+
}
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfigurationTests.java
similarity index 73%
rename from org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationTests.java
rename to org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfigurationTests.java
index 130342b24f4..2ce7795f76d 100644
--- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationTests.java
+++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfigurationTests.java
@@ -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>> converters = new Capture>>();
Capture conversionService = new Capture();
Capture> resolvers = new Capture>();
@@ -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 configurers = new ArrayList();
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>> converters = new Capture>>();
@@ -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 configurers = new ArrayList();
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() {
- }
-
- }
-
}
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/InterceptorConfigurerTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/InterceptorRegistryTests.java
similarity index 75%
rename from org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/InterceptorConfigurerTests.java
rename to org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/InterceptorRegistryTests.java
index 1f1534f6ea1..a0c8fa442fd 100644
--- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/InterceptorConfigurerTests.java
+++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/InterceptorRegistryTests.java
@@ -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 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 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 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 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 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 interceptors = getInterceptorsForPath("/path1");
- assertEquals(2, interceptors.size());
- verifyAdaptedInterceptor(interceptors.get(0), webRequestInterceptor1);
- verifyAdaptedInterceptor(interceptors.get(1), webRequestInterceptor2);
-
- assertEquals(0, getInterceptorsForPath("/path2").size());
- }
-
private List getInterceptorsForPath(String lookupPath) {
PathMatcher pathMatcher = new AntPathMatcher();
List result = new ArrayList();
- for (Object i : configurer.getInterceptors()) {
+ for (Object i : registry.getInterceptors()) {
if (i instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor) i;
if (mappedInterceptor.matches(lookupPath, pathMatcher)) {
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/ResourceConfigurerTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java
similarity index 55%
rename from org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/ResourceConfigurerTests.java
rename to org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java
index ba8d59488a7..145e1b7a6c9 100644
--- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/ResourceConfigurerTests.java
+++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/ResourceHandlerRegistryTests.java
@@ -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);
}
}
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/ViewControllerConfigurerTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistryTests.java
similarity index 59%
rename from org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/ViewControllerConfigurerTests.java
rename to org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistryTests.java
index f0edd47decf..b6e3ad28385 100644
--- a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/ViewControllerConfigurerTests.java
+++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/ViewControllerRegistryTests.java
@@ -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 urlMap = configurer.getHandlerMapping().getUrlMap();
- assertTrue(urlMap.isEmpty());
+ public void noViewControllers() throws Exception {
+ assertNull(registry.getHandlerMapping());
}
@Test
- public void mapViewName() {
- configurer.mapViewName("/path", "viewName");
- Map urlMap = configurer.getHandlerMapping().getUrlMap();
- ParameterizableViewController controller = (ParameterizableViewController) urlMap.get("/path");
- assertNotNull(controller);
- assertEquals("viewName", controller.getViewName());
- }
-
- @Test
- public void mapViewNameByConvention() {
- configurer.mapViewNameByConvention("/path");
- Map urlMap = configurer.getHandlerMapping().getUrlMap();
+ public void addViewController() {
+ registry.addViewController("/path");
+ Map urlMap = getHandlerMapping().getUrlMap();
ParameterizableViewController controller = (ParameterizableViewController) urlMap.get("/path");
assertNotNull(controller);
assertNull(controller.getViewName());
}
+ @Test
+ public void addViewControllerWithViewName() {
+ registry.addViewController("/path").setViewName("viewName");
+ Map 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();
+ }
+
}
diff --git a/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java
new file mode 100644
index 00000000000..08ae16db95d
--- /dev/null
+++ b/org.springframework.web.servlet/src/test/java/org/springframework/web/servlet/config/annotation/WebMvcConfigurationSupportTests.java
@@ -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> expectedConverters = new ArrayList>();
+ 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 expectedResolvers = new ArrayList();
+ 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 argResolvers= (List)
+ new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers");
+ assertEquals(1, argResolvers.size());
+
+ @SuppressWarnings("unchecked")
+ List handlers = (List)
+ 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() {
+ public String convert(TestBean source) {
+ return "converted";
+ }
+ });
+ }
+
+ @Override
+ public void configureMessageConverters(List> 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 argumentResolvers) {
+ argumentResolvers.add(new ModelAttributeMethodProcessor(true));
+ }
+
+ @Override
+ public void addReturnValueHandlers(List returnValueHandlers) {
+ returnValueHandlers.add(new DefaultMethodReturnValueHandler());
+ }
+
+ @Override
+ public void configureHandlerExceptionResolvers(List 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");
+ }
+ }
+
+}