23 changed files with 1098 additions and 764 deletions
@ -1,134 +0,0 @@
@@ -1,134 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.web.servlet.config.annotation; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.util.Assert; |
||||
import org.springframework.web.context.request.WebRequestInterceptor; |
||||
import org.springframework.web.servlet.HandlerInterceptor; |
||||
import org.springframework.web.servlet.handler.MappedInterceptor; |
||||
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter; |
||||
|
||||
/** |
||||
* Helps with configuring an ordered set of Spring MVC interceptors of type {@link HandlerInterceptor} or |
||||
* {@link WebRequestInterceptor}. Interceptors can be registered with a set of path patterns. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @since 3.1 |
||||
*/ |
||||
public class InterceptorConfigurer { |
||||
|
||||
private final List<Object> interceptors = new ArrayList<Object>(); |
||||
|
||||
/** |
||||
* Add a {@link HandlerInterceptor} that should apply to any request. |
||||
*/ |
||||
public void addInterceptor(HandlerInterceptor interceptor) { |
||||
register(interceptor); |
||||
} |
||||
|
||||
/** |
||||
* Add a {@link WebRequestInterceptor} that should apply to any request. |
||||
*/ |
||||
public void addInterceptor(WebRequestInterceptor interceptor) { |
||||
register(asHandlerInterceptorArray(interceptor)); |
||||
} |
||||
|
||||
/** |
||||
* Add {@link HandlerInterceptor}s that should apply to any request. |
||||
*/ |
||||
public void addInterceptors(HandlerInterceptor... interceptors) { |
||||
register( interceptors); |
||||
} |
||||
|
||||
/** |
||||
* Add {@link WebRequestInterceptor}s that should apply to any request. |
||||
*/ |
||||
public void addInterceptors(WebRequestInterceptor... interceptors) { |
||||
register(asHandlerInterceptorArray(interceptors)); |
||||
} |
||||
|
||||
/** |
||||
* Add a {@link HandlerInterceptor} with a set of URL path patterns it should apply to. |
||||
*/ |
||||
public void mapInterceptor(String[] pathPatterns, HandlerInterceptor interceptor) { |
||||
registerMappedInterceptors(pathPatterns, interceptor); |
||||
} |
||||
|
||||
/** |
||||
* Add a {@link WebRequestInterceptor} with a set of URL path patterns it should apply to. |
||||
*/ |
||||
public void mapInterceptor(String[] pathPatterns, WebRequestInterceptor interceptors) { |
||||
registerMappedInterceptors(pathPatterns, asHandlerInterceptorArray(interceptors)); |
||||
} |
||||
|
||||
/** |
||||
* Add {@link HandlerInterceptor}s with a set of URL path patterns they should apply to. |
||||
*/ |
||||
public void mapInterceptors(String[] pathPatterns, HandlerInterceptor... interceptors) { |
||||
registerMappedInterceptors(pathPatterns, interceptors); |
||||
} |
||||
|
||||
/** |
||||
* Add {@link WebRequestInterceptor}s with a set of URL path patterns they should apply to. |
||||
*/ |
||||
public void mapInterceptors(String[] pathPatterns, WebRequestInterceptor... interceptors) { |
||||
registerMappedInterceptors(pathPatterns, asHandlerInterceptorArray(interceptors)); |
||||
} |
||||
|
||||
private static HandlerInterceptor[] asHandlerInterceptorArray(WebRequestInterceptor...interceptors) { |
||||
HandlerInterceptor[] result = new HandlerInterceptor[interceptors.length]; |
||||
for (int i = 0; i < result.length; i++) { |
||||
result[i] = new WebRequestHandlerInterceptorAdapter(interceptors[i]); |
||||
} |
||||
return result; |
||||
} |
||||
|
||||
/** |
||||
* Stores the given set of {@link HandlerInterceptor}s internally. |
||||
* @param interceptors one or more interceptors to be stored |
||||
*/ |
||||
protected void register(HandlerInterceptor...interceptors) { |
||||
Assert.notEmpty(interceptors, "At least one interceptor must be provided"); |
||||
for (HandlerInterceptor interceptor : interceptors) { |
||||
this.interceptors.add(interceptor); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Stores the given set of {@link HandlerInterceptor}s and path patterns internally. |
||||
* @param pathPatterns path patterns or {@code null} |
||||
* @param interceptors one or more interceptors to be stored |
||||
*/ |
||||
protected void registerMappedInterceptors(String[] pathPatterns, HandlerInterceptor...interceptors) { |
||||
Assert.notEmpty(interceptors, "At least one interceptor must be provided"); |
||||
Assert.notEmpty(pathPatterns, "Path patterns must be provided"); |
||||
for (HandlerInterceptor interceptor : interceptors) { |
||||
this.interceptors.add(new MappedInterceptor(pathPatterns, interceptor)); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Returns all registered interceptors. |
||||
*/ |
||||
protected List<Object> getInterceptors() { |
||||
return interceptors; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.web.servlet.config.annotation; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.Arrays; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.util.Assert; |
||||
import org.springframework.web.servlet.HandlerInterceptor; |
||||
import org.springframework.web.servlet.handler.MappedInterceptor; |
||||
|
||||
/** |
||||
* Encapsulates a {@link HandlerInterceptor} and an optional list of URL patterns. |
||||
* Results in the creation of a {@link MappedInterceptor} if URL patterns are provided. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @author Keith Donald |
||||
* @since 3.1 |
||||
*/ |
||||
public class InterceptorRegistration { |
||||
|
||||
private final HandlerInterceptor interceptor; |
||||
|
||||
private final List<String> pathPatterns = new ArrayList<String>(); |
||||
|
||||
/** |
||||
* Creates an {@link InterceptorRegistration} instance. |
||||
*/ |
||||
public InterceptorRegistration(HandlerInterceptor interceptor) { |
||||
Assert.notNull(interceptor, "Interceptor is required"); |
||||
this.interceptor = interceptor; |
||||
} |
||||
|
||||
/** |
||||
* Adds one or more URL patterns to which the registered interceptor should apply to. |
||||
* If no URL patterns are provided, the interceptor applies to all paths. |
||||
*/ |
||||
public void addPathPatterns(String... pathPatterns) { |
||||
this.pathPatterns.addAll(Arrays.asList(pathPatterns)); |
||||
} |
||||
|
||||
/** |
||||
* Returns the underlying interceptor. If URL patterns are provided the returned type is |
||||
* {@link MappedInterceptor}; otherwise {@link HandlerInterceptor}. |
||||
*/ |
||||
protected Object getInterceptor() { |
||||
if (pathPatterns.isEmpty()) { |
||||
return interceptor; |
||||
} |
||||
return new MappedInterceptor(pathPatterns.toArray(new String[pathPatterns.size()]), interceptor); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,75 @@
@@ -0,0 +1,75 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.web.servlet.config.annotation; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.web.context.request.WebRequestInterceptor; |
||||
import org.springframework.web.servlet.HandlerInterceptor; |
||||
import org.springframework.web.servlet.handler.WebRequestHandlerInterceptorAdapter; |
||||
|
||||
/** |
||||
* Stores and provides access to a list of interceptors. For each interceptor you can optionally |
||||
* specify one or more URL patterns it applies to. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @author Keith Donald |
||||
* |
||||
* @since 3.1 |
||||
*/ |
||||
public class InterceptorRegistry { |
||||
|
||||
private final List<InterceptorRegistration> registrations = new ArrayList<InterceptorRegistration>(); |
||||
|
||||
/** |
||||
* Adds the provided {@link HandlerInterceptor}. |
||||
* @param interceptor the interceptor to add |
||||
* @return An {@link InterceptorRegistration} that allows you optionally configure the |
||||
* registered interceptor further for example adding URL patterns it should apply to. |
||||
*/ |
||||
public InterceptorRegistration addInterceptor(HandlerInterceptor interceptor) { |
||||
InterceptorRegistration registration = new InterceptorRegistration(interceptor); |
||||
registrations.add(registration); |
||||
return registration; |
||||
} |
||||
|
||||
/** |
||||
* Adds the provided {@link WebRequestInterceptor}. |
||||
* @param interceptor the interceptor to add |
||||
* @return An {@link InterceptorRegistration} that allows you optionally configure the |
||||
* registered interceptor further for example adding URL patterns it should apply to. |
||||
*/ |
||||
public InterceptorRegistration addWebRequestInterceptor(WebRequestInterceptor interceptor) { |
||||
WebRequestHandlerInterceptorAdapter adapted = new WebRequestHandlerInterceptorAdapter(interceptor); |
||||
InterceptorRegistration registration = new InterceptorRegistration(adapted); |
||||
registrations.add(registration); |
||||
return registration; |
||||
} |
||||
|
||||
/** |
||||
* Returns all registered interceptors. |
||||
*/ |
||||
protected List<Object> getInterceptors() { |
||||
List<Object> interceptors = new ArrayList<Object>(); |
||||
for (InterceptorRegistration registration : registrations) { |
||||
interceptors.add(registration.getInterceptor()); |
||||
} |
||||
return interceptors ; |
||||
} |
||||
|
||||
} |
||||
@ -1,197 +0,0 @@
@@ -1,197 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.web.servlet.config.annotation; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import javax.servlet.ServletContext; |
||||
|
||||
import org.springframework.context.ApplicationContext; |
||||
import org.springframework.core.io.Resource; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.CollectionUtils; |
||||
import org.springframework.web.HttpRequestHandler; |
||||
import org.springframework.web.servlet.HandlerMapping; |
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; |
||||
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; |
||||
|
||||
/** |
||||
* Helps with configuring a handler for serving static resources such as images, css files and others through |
||||
* Spring MVC including setting cache headers optimized for efficient loading in a web browser. Resources can |
||||
* be served out of locations under web application root, from the classpath, and others. |
||||
* |
||||
* <p>To configure resource handling, use {@link #addPathMappings(String...)} to add one or more URL path patterns |
||||
* within the current Servlet context, to use for serving resources from the handler, such as {@code "/resources/**"}. |
||||
* |
||||
* <p>Then use {@link #addResourceLocations(String...)} to add one or more locations from which to serve |
||||
* static content. For example, {{@code "/"}, {@code "classpath:/META-INF/public-web-resources/"}} allows resources |
||||
* to be served both from the web application root and from any JAR on the classpath that contains a |
||||
* {@code /META-INF/public-web-resources/} directory, with resources in the web application root taking precedence. |
||||
* |
||||
* <p>Optionally use {@link #setCachePeriod(Integer)} to specify the cache period for the resources served by the |
||||
* handler and {@link #setOrder(int)} to set the order in which to serve requests relative to other |
||||
* {@link HandlerMapping} instances in the Spring MVC web application context. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @since 3.1 |
||||
* |
||||
* @see DefaultServletHandlerConfigurer |
||||
*/ |
||||
public class ResourceConfigurer { |
||||
|
||||
private final List<String> pathPatterns = new ArrayList<String>(); |
||||
|
||||
private final List<Resource> locations = new ArrayList<Resource>(); |
||||
|
||||
private Integer cachePeriod; |
||||
|
||||
private int order = Integer.MAX_VALUE -1; |
||||
|
||||
private final ServletContext servletContext; |
||||
|
||||
private final ApplicationContext applicationContext; |
||||
|
||||
public ResourceConfigurer(ApplicationContext applicationContext, ServletContext servletContext) { |
||||
Assert.notNull(applicationContext, "ApplicationContext is required"); |
||||
this.applicationContext = applicationContext; |
||||
this.servletContext = servletContext; |
||||
} |
||||
|
||||
/** |
||||
* Add a URL path pattern within the current Servlet context to use for serving static resources |
||||
* using the Spring MVC {@link ResourceHttpRequestHandler}, for example {@code "/resources/**"}. |
||||
* @return the same {@link ResourceConfigurer} instance for chained method invocation |
||||
*/ |
||||
public ResourceConfigurer addPathMapping(String pathPattern) { |
||||
return addPathMappings(pathPattern); |
||||
} |
||||
|
||||
/** |
||||
* Add several URL path patterns within the current Servlet context to use for serving static resources |
||||
* using the Spring MVC {@link ResourceHttpRequestHandler}, for example {@code "/resources/**"}. |
||||
* @return the same {@link ResourceConfigurer} instance for chained method invocation |
||||
*/ |
||||
public ResourceConfigurer addPathMappings(String...pathPatterns) { |
||||
for (String path : pathPatterns) { |
||||
this.pathPatterns.add(path); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Add resource location from which to serve static content. The location must point to a valid |
||||
* directory. <p>For example, a value of {@code "/"} will allow resources to be served both from the web |
||||
* application root. Also see {@link #addResourceLocations(String...)} for mapping several resource locations. |
||||
* @return the same {@link ResourceConfigurer} instance for chained method invocation |
||||
*/ |
||||
public ResourceConfigurer addResourceLocation(String resourceLocation) { |
||||
return addResourceLocations(resourceLocation); |
||||
} |
||||
|
||||
/** |
||||
* Add one or more resource locations from which to serve static content. Each location must point to a valid |
||||
* directory. Multiple locations may be specified as a comma-separated list, and the locations will be checked |
||||
* for a given resource in the order specified. |
||||
* <p>For example, {{@code "/"}, {@code "classpath:/META-INF/public-web-resources/"}} allows resources to |
||||
* be served both from the web application root and from any JAR on the classpath that contains a |
||||
* {@code /META-INF/public-web-resources/} directory, with resources in the web application root taking precedence. |
||||
* @return the same {@link ResourceConfigurer} instance for chained method invocation |
||||
*/ |
||||
public ResourceConfigurer addResourceLocations(String...resourceLocations) { |
||||
for (String location : resourceLocations) { |
||||
this.locations.add(applicationContext.getResource(location)); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Specify the cache period for the resources served by the resource handler, in seconds. The default is to not |
||||
* send any cache headers but to rely on last-modified timestamps only. Set to 0 in order to send cache headers |
||||
* that prevent caching, or to a positive number of seconds to send cache headers with the given max-age value. |
||||
* @param cachePeriod the time to cache resources in seconds |
||||
* @return the same {@link ResourceConfigurer} instance for chained method invocation |
||||
*/ |
||||
public ResourceConfigurer setCachePeriod(Integer cachePeriod) { |
||||
this.cachePeriod = cachePeriod; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Get the cache period for static resources served by the resource handler. |
||||
*/ |
||||
public Integer getCachePeriod() { |
||||
return cachePeriod; |
||||
} |
||||
|
||||
/** |
||||
* Specify the order in which to serve static resources relative to other {@link HandlerMapping} instances in the |
||||
* Spring MVC web application context. The default value is {@code Integer.MAX_VALUE-1}. |
||||
*/ |
||||
public ResourceConfigurer setOrder(int order) { |
||||
this.order = order; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Get the order in which to serve static resources relative other {@link HandlerMapping} instances. |
||||
* @return the same {@link ResourceConfigurer} instance for chained method invocation |
||||
*/ |
||||
public Integer getOrder() { |
||||
return order; |
||||
} |
||||
|
||||
/** |
||||
* Return a {@link SimpleUrlHandlerMapping} with a {@link ResourceHttpRequestHandler} mapped to one or more |
||||
* URL path patterns. If the no path patterns were specified, the HandlerMapping returned contains an empty map. |
||||
*/ |
||||
protected SimpleUrlHandlerMapping getHandlerMapping() { |
||||
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping(); |
||||
handlerMapping.setOrder(order); |
||||
handlerMapping.setUrlMap(getUrlMap()); |
||||
return handlerMapping; |
||||
} |
||||
|
||||
private Map<String, HttpRequestHandler> getUrlMap() { |
||||
Map<String, HttpRequestHandler> urlMap = new LinkedHashMap<String, HttpRequestHandler>(); |
||||
if (!pathPatterns.isEmpty()) { |
||||
ResourceHttpRequestHandler requestHandler = createRequestHandler(); |
||||
for (String pathPattern : pathPatterns) { |
||||
urlMap.put(pathPattern, requestHandler); |
||||
} |
||||
} |
||||
return urlMap; |
||||
} |
||||
|
||||
/** |
||||
* Create a {@link ResourceHttpRequestHandler} instance. |
||||
*/ |
||||
protected ResourceHttpRequestHandler createRequestHandler() { |
||||
Assert.isTrue(!CollectionUtils.isEmpty(locations), "Path patterns specified but not resource locations."); |
||||
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler(); |
||||
requestHandler.setApplicationContext(applicationContext); |
||||
requestHandler.setServletContext(servletContext); |
||||
requestHandler.setLocations(locations); |
||||
if (cachePeriod != null) { |
||||
requestHandler.setCacheSeconds(cachePeriod); |
||||
} |
||||
return requestHandler; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,105 @@
@@ -0,0 +1,105 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.web.servlet.config.annotation; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import org.springframework.core.io.Resource; |
||||
import org.springframework.core.io.ResourceLoader; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.util.CollectionUtils; |
||||
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; |
||||
|
||||
/** |
||||
* Encapsulates information required to create a resource handlers. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @author Keith Donald |
||||
* |
||||
* @since 3.1 |
||||
*/ |
||||
public class ResourceHandlerRegistration { |
||||
|
||||
private final ResourceLoader resourceLoader; |
||||
|
||||
private final String[] pathPatterns; |
||||
|
||||
private final List<Resource> locations = new ArrayList<Resource>(); |
||||
|
||||
private Integer cachePeriod; |
||||
|
||||
/** |
||||
* Create a {@link ResourceHandlerRegistration} instance. |
||||
* @param resourceLoader a resource loader for turning a String location into a {@link Resource} |
||||
* @param pathPatterns one or more resource URL path patterns |
||||
*/ |
||||
public ResourceHandlerRegistration(ResourceLoader resourceLoader, String... pathPatterns) { |
||||
Assert.notEmpty(pathPatterns, "At least one path pattern is required for resource handling."); |
||||
this.resourceLoader = resourceLoader; |
||||
this.pathPatterns = pathPatterns; |
||||
} |
||||
|
||||
/** |
||||
* Add one or more resource locations from which to serve static content. Each location must point to a valid |
||||
* directory. Multiple locations may be specified as a comma-separated list, and the locations will be checked |
||||
* for a given resource in the order specified. |
||||
* <p>For example, {{@code "/"}, {@code "classpath:/META-INF/public-web-resources/"}} allows resources to |
||||
* be served both from the web application root and from any JAR on the classpath that contains a |
||||
* {@code /META-INF/public-web-resources/} directory, with resources in the web application root taking precedence. |
||||
* @return the same {@link ResourceHandlerRegistration} instance for chained method invocation |
||||
*/ |
||||
public ResourceHandlerRegistration addResourceLocations(String...resourceLocations) { |
||||
for (String location : resourceLocations) { |
||||
this.locations.add(resourceLoader.getResource(location)); |
||||
} |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Specify the cache period for the resources served by the resource handler, in seconds. The default is to not |
||||
* send any cache headers but to rely on last-modified timestamps only. Set to 0 in order to send cache headers |
||||
* that prevent caching, or to a positive number of seconds to send cache headers with the given max-age value. |
||||
* @param cachePeriod the time to cache resources in seconds |
||||
* @return the same {@link ResourceHandlerRegistration} instance for chained method invocation |
||||
*/ |
||||
public ResourceHandlerRegistration setCachePeriod(Integer cachePeriod) { |
||||
this.cachePeriod = cachePeriod; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Returns the URL path patterns for the resource handler. |
||||
*/ |
||||
protected String[] getPathPatterns() { |
||||
return pathPatterns; |
||||
} |
||||
|
||||
/** |
||||
* Returns a {@link ResourceHttpRequestHandler} instance. |
||||
*/ |
||||
protected ResourceHttpRequestHandler getRequestHandler() { |
||||
Assert.isTrue(!CollectionUtils.isEmpty(locations), "At least one location is required for resource handling."); |
||||
ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler(); |
||||
requestHandler.setLocations(locations); |
||||
if (cachePeriod != null) { |
||||
requestHandler.setCacheSeconds(cachePeriod); |
||||
} |
||||
return requestHandler; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,111 @@
@@ -0,0 +1,111 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.web.servlet.config.annotation; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import javax.servlet.ServletContext; |
||||
|
||||
import org.springframework.context.ApplicationContext; |
||||
import org.springframework.util.Assert; |
||||
import org.springframework.web.HttpRequestHandler; |
||||
import org.springframework.web.servlet.HandlerMapping; |
||||
import org.springframework.web.servlet.handler.AbstractHandlerMapping; |
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; |
||||
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler; |
||||
|
||||
/** |
||||
* Stores registrations of resource handlers for serving static resources such as images, css files and others |
||||
* through Spring MVC including setting cache headers optimized for efficient loading in a web browser. |
||||
* Resources can be served out of locations under web application root, from the classpath, and others. |
||||
* |
||||
* <p>To create a resource handler, use {@link #addResourceHandler(String...)} providing the URL path patterns |
||||
* for which the handler should be invoked to serve static resources (e.g. {@code "/resources/**"}). |
||||
* |
||||
* <p>Then use additional methods on the returned {@link ResourceHandlerRegistration} to add one or more |
||||
* locations from which to serve static content from (e.g. {{@code "/"}, |
||||
* {@code "classpath:/META-INF/public-web-resources/"}}) or to specify a cache period for served resources. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @since 3.1 |
||||
* |
||||
* @see DefaultServletHandlerConfigurer |
||||
*/ |
||||
public class ResourceHandlerRegistry { |
||||
|
||||
private final ServletContext servletContext; |
||||
|
||||
private final ApplicationContext applicationContext; |
||||
|
||||
private final List<ResourceHandlerRegistration> registrations = new ArrayList<ResourceHandlerRegistration>(); |
||||
|
||||
private int order = Integer.MAX_VALUE -1; |
||||
|
||||
public ResourceHandlerRegistry(ApplicationContext applicationContext, ServletContext servletContext) { |
||||
Assert.notNull(applicationContext, "ApplicationContext is required"); |
||||
this.applicationContext = applicationContext; |
||||
this.servletContext = servletContext; |
||||
} |
||||
|
||||
/** |
||||
* Add a resource handler for serving static resources based on the specified URL path patterns. |
||||
* The handler will be invoked for every incoming request that matches to one of the specified path patterns. |
||||
* @return A {@link ResourceHandlerRegistration} to use to further configure the registered resource handler. |
||||
*/ |
||||
public ResourceHandlerRegistration addResourceHandler(String... pathPatterns) { |
||||
ResourceHandlerRegistration registration = new ResourceHandlerRegistration(applicationContext, pathPatterns); |
||||
registrations.add(registration); |
||||
return registration; |
||||
} |
||||
|
||||
/** |
||||
* Specify the order to use for resource handling relative to other {@link HandlerMapping}s configured in |
||||
* the Spring MVC application context. The default value used is {@code Integer.MAX_VALUE-1}. |
||||
*/ |
||||
public ResourceHandlerRegistry setOrder(int order) { |
||||
this.order = order; |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Return a handler mapping with the mapped resource handlers; or {@code null} in case of no registrations. |
||||
*/ |
||||
protected AbstractHandlerMapping getHandlerMapping() { |
||||
if (registrations.isEmpty()) { |
||||
return null; |
||||
} |
||||
|
||||
Map<String, HttpRequestHandler> urlMap = new LinkedHashMap<String, HttpRequestHandler>(); |
||||
for (ResourceHandlerRegistration registration : registrations) { |
||||
for (String pathPattern : registration.getPathPatterns()) { |
||||
ResourceHttpRequestHandler requestHandler = registration.getRequestHandler(); |
||||
requestHandler.setServletContext(servletContext); |
||||
requestHandler.setApplicationContext(applicationContext); |
||||
urlMap.put(pathPattern, requestHandler); |
||||
} |
||||
} |
||||
|
||||
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping(); |
||||
handlerMapping.setOrder(order); |
||||
handlerMapping.setUrlMap(urlMap); |
||||
return handlerMapping; |
||||
} |
||||
|
||||
} |
||||
@ -1,87 +0,0 @@
@@ -1,87 +0,0 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.web.servlet.config.annotation; |
||||
|
||||
import java.util.LinkedHashMap; |
||||
import java.util.Map; |
||||
|
||||
import org.springframework.web.servlet.HandlerMapping; |
||||
import org.springframework.web.servlet.RequestToViewNameTranslator; |
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; |
||||
import org.springframework.web.servlet.mvc.Controller; |
||||
import org.springframework.web.servlet.mvc.ParameterizableViewController; |
||||
|
||||
/** |
||||
* Helps with view controllers. View controllers provide a direct mapping between a URL path and view name. This is |
||||
* useful when serving requests that don't require application-specific controller logic and can be forwarded |
||||
* directly to a view for rendering. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @since 3.1 |
||||
*/ |
||||
public class ViewControllerConfigurer { |
||||
|
||||
private final Map<String, Controller> urlMap = new LinkedHashMap<String, Controller>(); |
||||
|
||||
private int order = 1; |
||||
|
||||
/** |
||||
* Map the URL path to a view name derived by convention through the DispatcherServlet's |
||||
* {@link RequestToViewNameTranslator}. |
||||
* @return the same {@link ViewControllerConfigurer} instance for convenient chained method invocation |
||||
*/ |
||||
public ViewControllerConfigurer mapViewNameByConvention(String urlPath) { |
||||
return mapViewName(urlPath, null); |
||||
} |
||||
|
||||
/** |
||||
* Map the URL path to the specified view name. |
||||
* @return the same {@link ViewControllerConfigurer} instance for convenient chained method invocation |
||||
*/ |
||||
public ViewControllerConfigurer mapViewName(String urlPath, String viewName) { |
||||
ParameterizableViewController controller = new ParameterizableViewController(); |
||||
controller.setViewName(viewName); |
||||
urlMap.put(urlPath, controller); |
||||
return this; |
||||
} |
||||
|
||||
/** |
||||
* Specify the order in which to check view controller path mappings relative to other {@link HandlerMapping} |
||||
* instances in the Spring MVC web application context. The default value is 1. |
||||
*/ |
||||
public void setOrder(int order) { |
||||
this.order = order; |
||||
} |
||||
|
||||
/** |
||||
* Get the order in which to check view controller path mappings relative to other {@link HandlerMapping}s. |
||||
*/ |
||||
public int getOrder() { |
||||
return order; |
||||
} |
||||
|
||||
/** |
||||
* Return a {@link SimpleUrlHandlerMapping} with URL path to view controllers mappings. |
||||
*/ |
||||
protected SimpleUrlHandlerMapping getHandlerMapping() { |
||||
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping(); |
||||
handlerMapping.setOrder(order); |
||||
handlerMapping.setUrlMap(urlMap); |
||||
return handlerMapping; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,70 @@
@@ -0,0 +1,70 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.web.servlet.config.annotation; |
||||
|
||||
import org.springframework.util.Assert; |
||||
import org.springframework.web.servlet.RequestToViewNameTranslator; |
||||
import org.springframework.web.servlet.mvc.ParameterizableViewController; |
||||
|
||||
/** |
||||
* Encapsulates information required to create a view controller. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @author Keith Donald |
||||
* @since 3.1 |
||||
*/ |
||||
public class ViewControllerRegistration { |
||||
|
||||
private final String urlPath; |
||||
|
||||
private String viewName; |
||||
|
||||
/** |
||||
* Creates a {@link ViewControllerRegistration} with the given URL path. When a request matches |
||||
* to the given URL path this view controller will process it. |
||||
*/ |
||||
public ViewControllerRegistration(String urlPath) { |
||||
Assert.notNull(urlPath, "A URL path is required to create a view controller."); |
||||
this.urlPath = urlPath; |
||||
} |
||||
|
||||
/** |
||||
* Sets the view name to use for this view controller. This field is optional. If not specified the |
||||
* view controller will return a {@code null} view name, which will be resolved through the configured |
||||
* {@link RequestToViewNameTranslator}. By default that means "/foo/bar" would resolve to "foo/bar". |
||||
*/ |
||||
public void setViewName(String viewName) { |
||||
this.viewName = viewName; |
||||
} |
||||
|
||||
/** |
||||
* Returns the URL path for the view controller. |
||||
*/ |
||||
protected String getUrlPath() { |
||||
return urlPath; |
||||
} |
||||
|
||||
/** |
||||
* Returns the view controllers. |
||||
*/ |
||||
protected Object getViewController() { |
||||
ParameterizableViewController controller = new ParameterizableViewController(); |
||||
controller.setViewName(viewName); |
||||
return controller; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,77 @@
@@ -0,0 +1,77 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.web.servlet.config.annotation; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.LinkedHashMap; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
|
||||
import org.springframework.web.servlet.HandlerMapping; |
||||
import org.springframework.web.servlet.handler.AbstractHandlerMapping; |
||||
import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping; |
||||
|
||||
/** |
||||
* Stores registrations of view controllers. A view controller does nothing more than return a specified |
||||
* view name. It saves you from having to write a controller when you want to forward the request straight |
||||
* through to a view such as a JSP. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
* @author Keith Donald |
||||
* @since 3.1 |
||||
*/ |
||||
public class ViewControllerRegistry { |
||||
|
||||
private final List<ViewControllerRegistration> registrations = new ArrayList<ViewControllerRegistration>(); |
||||
|
||||
private int order = 1; |
||||
|
||||
public ViewControllerRegistration addViewController(String urlPath) { |
||||
ViewControllerRegistration registration = new ViewControllerRegistration(urlPath); |
||||
registrations.add(registration); |
||||
return registration; |
||||
} |
||||
|
||||
/** |
||||
* Specify the order to use for ViewControllers mappings relative to other {@link HandlerMapping}s |
||||
* configured in the Spring MVC application context. The default value for view controllers is 1, |
||||
* which is 1 higher than the value used for annotated controllers. |
||||
*/ |
||||
public void setOrder(int order) { |
||||
this.order = order; |
||||
} |
||||
|
||||
/** |
||||
* Returns a handler mapping with the mapped ViewControllers; or {@code null} in case of no registrations. |
||||
*/ |
||||
protected AbstractHandlerMapping getHandlerMapping() { |
||||
if (registrations.isEmpty()) { |
||||
return null; |
||||
} |
||||
|
||||
Map<String, Object> urlMap = new LinkedHashMap<String, Object>(); |
||||
for (ViewControllerRegistration registration : registrations) { |
||||
urlMap.put(registration.getUrlPath(), registration.getViewController()); |
||||
} |
||||
|
||||
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping(); |
||||
handlerMapping.setOrder(order); |
||||
handlerMapping.setUrlMap(urlMap); |
||||
return handlerMapping; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,315 @@
@@ -0,0 +1,315 @@
|
||||
/* |
||||
* Copyright 2002-2011 the original author or authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
*/ |
||||
|
||||
package org.springframework.web.servlet.config.annotation; |
||||
|
||||
import static org.junit.Assert.assertEquals; |
||||
import static org.junit.Assert.assertNotNull; |
||||
import static org.junit.Assert.assertTrue; |
||||
|
||||
import java.util.ArrayList; |
||||
import java.util.List; |
||||
|
||||
import javax.servlet.http.HttpServletRequest; |
||||
|
||||
import org.junit.Before; |
||||
import org.junit.Test; |
||||
import org.springframework.beans.DirectFieldAccessor; |
||||
import org.springframework.beans.TestBean; |
||||
import org.springframework.core.convert.ConversionService; |
||||
import org.springframework.core.convert.converter.Converter; |
||||
import org.springframework.core.io.FileSystemResourceLoader; |
||||
import org.springframework.format.FormatterRegistry; |
||||
import org.springframework.format.support.FormattingConversionService; |
||||
import org.springframework.http.converter.HttpMessageConverter; |
||||
import org.springframework.http.converter.json.MappingJacksonHttpMessageConverter; |
||||
import org.springframework.mock.web.MockHttpServletRequest; |
||||
import org.springframework.mock.web.MockServletContext; |
||||
import org.springframework.stereotype.Controller; |
||||
import org.springframework.validation.BeanPropertyBindingResult; |
||||
import org.springframework.validation.Errors; |
||||
import org.springframework.validation.Validator; |
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean; |
||||
import org.springframework.web.bind.annotation.RequestMapping; |
||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer; |
||||
import org.springframework.web.context.support.StaticWebApplicationContext; |
||||
import org.springframework.web.method.annotation.support.ModelAttributeMethodProcessor; |
||||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; |
||||
import org.springframework.web.method.support.HandlerMethodReturnValueHandler; |
||||
import org.springframework.web.servlet.HandlerExceptionResolver; |
||||
import org.springframework.web.servlet.HandlerExecutionChain; |
||||
import org.springframework.web.servlet.handler.AbstractHandlerMapping; |
||||
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping; |
||||
import org.springframework.web.servlet.handler.ConversionServiceExposingInterceptor; |
||||
import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite; |
||||
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver; |
||||
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor; |
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter; |
||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping; |
||||
import org.springframework.web.servlet.mvc.method.annotation.support.DefaultMethodReturnValueHandler; |
||||
|
||||
/** |
||||
* A test fixture for {@link WebMvcConfigurationSupport}. |
||||
* |
||||
* @author Rossen Stoyanchev |
||||
*/ |
||||
public class WebMvcConfigurationSupportTests { |
||||
|
||||
private TestWebMvcConfiguration mvcConfiguration; |
||||
|
||||
@Before |
||||
public void setUp() { |
||||
mvcConfiguration = new TestWebMvcConfiguration(); |
||||
} |
||||
|
||||
@Test |
||||
public void requestMappingHandlerMapping() throws Exception { |
||||
StaticWebApplicationContext cxt = new StaticWebApplicationContext(); |
||||
cxt.registerSingleton("controller", TestController.class); |
||||
|
||||
RequestMappingHandlerMapping handlerMapping = mvcConfiguration.requestMappingHandlerMapping(); |
||||
assertEquals(0, handlerMapping.getOrder()); |
||||
|
||||
handlerMapping.setApplicationContext(cxt); |
||||
HandlerExecutionChain chain = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/")); |
||||
assertNotNull(chain.getInterceptors()); |
||||
assertEquals(ConversionServiceExposingInterceptor.class, chain.getInterceptors()[0].getClass()); |
||||
} |
||||
|
||||
@Test |
||||
public void emptyViewControllerHandlerMapping() { |
||||
AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping) mvcConfiguration.viewControllerHandlerMapping(); |
||||
assertNotNull(handlerMapping); |
||||
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder()); |
||||
assertTrue(handlerMapping.getClass().getName().endsWith("EmptyHandlerMapping")); |
||||
} |
||||
|
||||
@Test |
||||
public void beanNameHandlerMapping() throws Exception { |
||||
StaticWebApplicationContext cxt = new StaticWebApplicationContext(); |
||||
cxt.registerSingleton("/controller", TestController.class); |
||||
|
||||
HttpServletRequest request = new MockHttpServletRequest("GET", "/controller"); |
||||
|
||||
BeanNameUrlHandlerMapping handlerMapping = mvcConfiguration.beanNameHandlerMapping(); |
||||
assertEquals(2, handlerMapping.getOrder()); |
||||
|
||||
handlerMapping.setApplicationContext(cxt); |
||||
HandlerExecutionChain chain = handlerMapping.getHandler(request); |
||||
assertNotNull(chain.getInterceptors()); |
||||
assertEquals(2, chain.getInterceptors().length); |
||||
assertEquals(ConversionServiceExposingInterceptor.class, chain.getInterceptors()[1].getClass()); |
||||
} |
||||
|
||||
@Test |
||||
public void emptyResourceHandlerMapping() { |
||||
mvcConfiguration.setApplicationContext(new StaticWebApplicationContext()); |
||||
AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping) mvcConfiguration.resourceHandlerMapping(); |
||||
assertNotNull(handlerMapping); |
||||
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder()); |
||||
assertTrue(handlerMapping.getClass().getName().endsWith("EmptyHandlerMapping")); |
||||
} |
||||
|
||||
@Test |
||||
public void emptyDefaultServletHandlerMapping() { |
||||
mvcConfiguration.setServletContext(new MockServletContext()); |
||||
AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping) mvcConfiguration.defaultServletHandlerMapping(); |
||||
assertNotNull(handlerMapping); |
||||
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder()); |
||||
assertTrue(handlerMapping.getClass().getName().endsWith("EmptyHandlerMapping")); |
||||
} |
||||
|
||||
@Test |
||||
public void requestMappingHandlerAdapter() throws Exception { |
||||
RequestMappingHandlerAdapter adapter = mvcConfiguration.requestMappingHandlerAdapter(); |
||||
|
||||
List<HttpMessageConverter<?>> expectedConverters = new ArrayList<HttpMessageConverter<?>>(); |
||||
mvcConfiguration.addDefaultHttpMessageConverters(expectedConverters); |
||||
assertEquals(expectedConverters.size(), adapter.getMessageConverters().size()); |
||||
|
||||
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer(); |
||||
assertNotNull(initializer); |
||||
|
||||
ConversionService conversionService = initializer.getConversionService(); |
||||
assertNotNull(conversionService); |
||||
assertTrue(conversionService instanceof FormattingConversionService); |
||||
|
||||
Validator validator = initializer.getValidator(); |
||||
assertNotNull(validator); |
||||
assertTrue(validator instanceof LocalValidatorFactoryBean); |
||||
} |
||||
|
||||
@Test |
||||
public void handlerExceptionResolver() throws Exception { |
||||
HandlerExceptionResolverComposite compositeResolver = |
||||
(HandlerExceptionResolverComposite) mvcConfiguration.handlerExceptionResolver(); |
||||
|
||||
assertEquals(0, compositeResolver.getOrder()); |
||||
|
||||
List<HandlerExceptionResolver> expectedResolvers = new ArrayList<HandlerExceptionResolver>(); |
||||
mvcConfiguration.addDefaultHandlerExceptionResolvers(expectedResolvers); |
||||
assertEquals(expectedResolvers.size(), compositeResolver.getExceptionResolvers().size()); |
||||
} |
||||
|
||||
@Test |
||||
public void webMvcConfigurerExtensionHooks() throws Exception { |
||||
|
||||
StaticWebApplicationContext appCxt = new StaticWebApplicationContext(); |
||||
appCxt.setServletContext(new MockServletContext(new FileSystemResourceLoader())); |
||||
appCxt.registerSingleton("controller", TestController.class); |
||||
|
||||
WebConfig webConfig = new WebConfig(); |
||||
webConfig.setApplicationContext(appCxt); |
||||
webConfig.setServletContext(appCxt.getServletContext()); |
||||
|
||||
String actual = webConfig.mvcConversionService().convert(new TestBean(), String.class); |
||||
assertEquals("converted", actual); |
||||
|
||||
RequestMappingHandlerAdapter adapter = webConfig.requestMappingHandlerAdapter(); |
||||
assertEquals(1, adapter.getMessageConverters().size()); |
||||
|
||||
ConfigurableWebBindingInitializer initializer = (ConfigurableWebBindingInitializer) adapter.getWebBindingInitializer(); |
||||
assertNotNull(initializer); |
||||
|
||||
BeanPropertyBindingResult bindingResult = new BeanPropertyBindingResult(null, ""); |
||||
initializer.getValidator().validate(null, bindingResult); |
||||
assertEquals("invalid", bindingResult.getAllErrors().get(0).getCode()); |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
List<HandlerMethodArgumentResolver> argResolvers= (List<HandlerMethodArgumentResolver>) |
||||
new DirectFieldAccessor(adapter).getPropertyValue("customArgumentResolvers"); |
||||
assertEquals(1, argResolvers.size()); |
||||
|
||||
@SuppressWarnings("unchecked") |
||||
List<HandlerMethodReturnValueHandler> handlers = (List<HandlerMethodReturnValueHandler>) |
||||
new DirectFieldAccessor(adapter).getPropertyValue("customReturnValueHandlers"); |
||||
assertEquals(1, handlers.size()); |
||||
|
||||
HandlerExceptionResolverComposite composite = (HandlerExceptionResolverComposite) webConfig.handlerExceptionResolver(); |
||||
assertEquals(1, composite.getExceptionResolvers().size()); |
||||
|
||||
RequestMappingHandlerMapping rmHandlerMapping = webConfig.requestMappingHandlerMapping(); |
||||
rmHandlerMapping.setApplicationContext(appCxt); |
||||
HandlerExecutionChain chain = rmHandlerMapping.getHandler(new MockHttpServletRequest("GET", "/")); |
||||
assertNotNull(chain.getInterceptors()); |
||||
assertEquals(2, chain.getInterceptors().length); |
||||
assertEquals(LocaleChangeInterceptor.class, chain.getInterceptors()[0].getClass()); |
||||
assertEquals(ConversionServiceExposingInterceptor.class, chain.getInterceptors()[1].getClass()); |
||||
|
||||
AbstractHandlerMapping handlerMapping = (AbstractHandlerMapping) webConfig.viewControllerHandlerMapping(); |
||||
handlerMapping.setApplicationContext(appCxt); |
||||
assertNotNull(handlerMapping); |
||||
assertEquals(1, handlerMapping.getOrder()); |
||||
HandlerExecutionChain handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/path")); |
||||
assertNotNull(handler.getHandler()); |
||||
|
||||
handlerMapping = (AbstractHandlerMapping) webConfig.resourceHandlerMapping(); |
||||
handlerMapping.setApplicationContext(appCxt); |
||||
assertNotNull(handlerMapping); |
||||
assertEquals(Integer.MAX_VALUE-1, handlerMapping.getOrder()); |
||||
handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/resources/foo.gif")); |
||||
assertNotNull(handler.getHandler()); |
||||
|
||||
handlerMapping = (AbstractHandlerMapping) webConfig.defaultServletHandlerMapping(); |
||||
handlerMapping.setApplicationContext(appCxt); |
||||
assertNotNull(handlerMapping); |
||||
assertEquals(Integer.MAX_VALUE, handlerMapping.getOrder()); |
||||
handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/anyPath")); |
||||
assertNotNull(handler.getHandler()); |
||||
} |
||||
|
||||
@Controller |
||||
private static class TestController { |
||||
|
||||
@SuppressWarnings("unused") |
||||
@RequestMapping("/") |
||||
public void handle() { |
||||
} |
||||
} |
||||
|
||||
private static class TestWebMvcConfiguration extends WebMvcConfigurationSupport { |
||||
|
||||
} |
||||
|
||||
/** |
||||
* The purpose of this class is to test that an implementation of a {@link WebMvcConfigurer} |
||||
* can also apply customizations by extension from {@link WebMvcConfigurationSupport}. |
||||
*/ |
||||
private class WebConfig extends WebMvcConfigurationSupport implements WebMvcConfigurer { |
||||
|
||||
@Override |
||||
public void addFormatters(FormatterRegistry registry) { |
||||
registry.addConverter(new Converter<TestBean, String>() { |
||||
public String convert(TestBean source) { |
||||
return "converted"; |
||||
} |
||||
}); |
||||
} |
||||
|
||||
@Override |
||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { |
||||
converters.add(new MappingJacksonHttpMessageConverter()); |
||||
} |
||||
|
||||
@Override |
||||
public Validator getValidator() { |
||||
return new Validator() { |
||||
public void validate(Object target, Errors errors) { |
||||
errors.reject("invalid"); |
||||
} |
||||
public boolean supports(Class<?> clazz) { |
||||
return true; |
||||
} |
||||
}; |
||||
} |
||||
|
||||
@Override |
||||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { |
||||
argumentResolvers.add(new ModelAttributeMethodProcessor(true)); |
||||
} |
||||
|
||||
@Override |
||||
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) { |
||||
returnValueHandlers.add(new DefaultMethodReturnValueHandler()); |
||||
} |
||||
|
||||
@Override |
||||
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) { |
||||
exceptionResolvers.add(new SimpleMappingExceptionResolver()); |
||||
} |
||||
|
||||
@Override |
||||
public void addInterceptors(InterceptorRegistry registry) { |
||||
registry.addInterceptor(new LocaleChangeInterceptor()); |
||||
} |
||||
|
||||
@Override |
||||
public void addViewControllers(ViewControllerRegistry registry) { |
||||
registry.addViewController("/path"); |
||||
} |
||||
|
||||
@Override |
||||
public void addResourceHandlers(ResourceHandlerRegistry registry) { |
||||
registry.addResourceHandler("/resources/**").addResourceLocations("src/test/java"); |
||||
} |
||||
|
||||
@Override |
||||
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { |
||||
configurer.enable("default"); |
||||
} |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue