Backport MVC Java config path-related config options
Issue: SPR-14186
This commit is contained in:
parent
3d6b0ca5be
commit
cf39078fbb
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -163,6 +163,8 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
handlerMappingDef.getPropertyValues().add("removeSemicolonContent", !enableMatrixVariables);
|
handlerMappingDef.getPropertyValues().add("removeSemicolonContent", !enableMatrixVariables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
configurePathMatchingProperties(handlerMappingDef, element, parserContext);
|
||||||
|
|
||||||
RuntimeBeanReference conversionService = getConversionService(element, source, parserContext);
|
RuntimeBeanReference conversionService = getConversionService(element, source, parserContext);
|
||||||
RuntimeBeanReference validator = getValidator(element, source, parserContext);
|
RuntimeBeanReference validator = getValidator(element, source, parserContext);
|
||||||
RuntimeBeanReference messageCodesResolver = getMessageCodesResolver(element);
|
RuntimeBeanReference messageCodesResolver = getMessageCodesResolver(element);
|
||||||
|
@ -309,6 +311,40 @@ class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
return contentNegotiationManagerRef;
|
return contentNegotiationManagerRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void configurePathMatchingProperties(RootBeanDefinition handlerMappingDef, Element element,
|
||||||
|
ParserContext parserContext) {
|
||||||
|
|
||||||
|
Element pathMatchingElement = DomUtils.getChildElementByTagName(element, "path-matching");
|
||||||
|
if (pathMatchingElement != null) {
|
||||||
|
Object source = parserContext.extractSource(element);
|
||||||
|
if (pathMatchingElement.hasAttribute("suffix-pattern")) {
|
||||||
|
Boolean useSuffixPatternMatch = Boolean.valueOf(pathMatchingElement.getAttribute("suffix-pattern"));
|
||||||
|
handlerMappingDef.getPropertyValues().add("useSuffixPatternMatch", useSuffixPatternMatch);
|
||||||
|
}
|
||||||
|
if (pathMatchingElement.hasAttribute("trailing-slash")) {
|
||||||
|
Boolean useTrailingSlashMatch = Boolean.valueOf(pathMatchingElement.getAttribute("trailing-slash"));
|
||||||
|
handlerMappingDef.getPropertyValues().add("useTrailingSlashMatch", useTrailingSlashMatch);
|
||||||
|
}
|
||||||
|
if (pathMatchingElement.hasAttribute("registered-suffixes-only")) {
|
||||||
|
Boolean useRegisteredSuffixPatternMatch = Boolean.valueOf(pathMatchingElement.getAttribute("registered-suffixes-only"));
|
||||||
|
handlerMappingDef.getPropertyValues().add("useRegisteredSuffixPatternMatch", useRegisteredSuffixPatternMatch);
|
||||||
|
}
|
||||||
|
RuntimeBeanReference pathHelperRef = null;
|
||||||
|
if (pathMatchingElement.hasAttribute("path-helper")) {
|
||||||
|
pathHelperRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-helper"));
|
||||||
|
}
|
||||||
|
pathHelperRef = MvcNamespaceUtils.registerUrlPathHelper(pathHelperRef, parserContext, source);
|
||||||
|
handlerMappingDef.getPropertyValues().add("urlPathHelper", pathHelperRef);
|
||||||
|
|
||||||
|
RuntimeBeanReference pathMatcherRef = null;
|
||||||
|
if (pathMatchingElement.hasAttribute("path-matcher")) {
|
||||||
|
pathMatcherRef = new RuntimeBeanReference(pathMatchingElement.getAttribute("path-matcher"));
|
||||||
|
}
|
||||||
|
pathMatcherRef = MvcNamespaceUtils.registerPathMatcher(pathMatcherRef, parserContext, source);
|
||||||
|
handlerMappingDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private Properties getDefaultMediaTypes() {
|
private Properties getDefaultMediaTypes() {
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
if (romePresent) {
|
if (romePresent) {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -17,12 +17,16 @@
|
||||||
package org.springframework.web.servlet.config;
|
package org.springframework.web.servlet.config;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||||
import org.springframework.beans.factory.support.RootBeanDefinition;
|
import org.springframework.beans.factory.support.RootBeanDefinition;
|
||||||
import org.springframework.beans.factory.xml.ParserContext;
|
import org.springframework.beans.factory.xml.ParserContext;
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
import org.springframework.util.PathMatcher;
|
||||||
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
|
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
|
||||||
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
import org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter;
|
||||||
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
|
import org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter;
|
||||||
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience methods for use in MVC namespace BeanDefinitionParsers.
|
* Convenience methods for use in MVC namespace BeanDefinitionParsers.
|
||||||
|
@ -41,12 +45,70 @@ abstract class MvcNamespaceUtils {
|
||||||
private static final String HTTP_REQUEST_HANDLER_ADAPTER_BEAN_NAME =
|
private static final String HTTP_REQUEST_HANDLER_ADAPTER_BEAN_NAME =
|
||||||
HttpRequestHandlerAdapter.class.getName();
|
HttpRequestHandlerAdapter.class.getName();
|
||||||
|
|
||||||
|
private static final String URL_PATH_HELPER_BEAN_NAME = "mvcUrlPathHelper";
|
||||||
|
|
||||||
|
private static final String PATH_MATCHER_BEAN_NAME = "mvcPathMatcher";
|
||||||
|
|
||||||
|
|
||||||
public static void registerDefaultComponents(ParserContext parserContext, Object source) {
|
public static void registerDefaultComponents(ParserContext parserContext, Object source) {
|
||||||
registerBeanNameUrlHandlerMapping(parserContext, source);
|
registerBeanNameUrlHandlerMapping(parserContext, source);
|
||||||
registerHttpRequestHandlerAdapter(parserContext, source);
|
registerHttpRequestHandlerAdapter(parserContext, source);
|
||||||
registerSimpleControllerHandlerAdapter(parserContext, source);
|
registerSimpleControllerHandlerAdapter(parserContext, source);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an alias to an existing well-known name or registers a new instance of a {@link UrlPathHelper}
|
||||||
|
* under that well-known name, unless already registered.
|
||||||
|
* @return a RuntimeBeanReference to this {@link UrlPathHelper} instance
|
||||||
|
* @since 3.2.17
|
||||||
|
*/
|
||||||
|
public static RuntimeBeanReference registerUrlPathHelper(RuntimeBeanReference urlPathHelperRef,
|
||||||
|
ParserContext parserContext, Object source) {
|
||||||
|
|
||||||
|
if (urlPathHelperRef != null) {
|
||||||
|
if (parserContext.getRegistry().isAlias(URL_PATH_HELPER_BEAN_NAME)) {
|
||||||
|
parserContext.getRegistry().removeAlias(URL_PATH_HELPER_BEAN_NAME);
|
||||||
|
}
|
||||||
|
parserContext.getRegistry().registerAlias(urlPathHelperRef.getBeanName(), URL_PATH_HELPER_BEAN_NAME);
|
||||||
|
}
|
||||||
|
else if (!parserContext.getRegistry().isAlias(URL_PATH_HELPER_BEAN_NAME)
|
||||||
|
&& !parserContext.getRegistry().containsBeanDefinition(URL_PATH_HELPER_BEAN_NAME)) {
|
||||||
|
RootBeanDefinition urlPathHelperDef = new RootBeanDefinition(UrlPathHelper.class);
|
||||||
|
urlPathHelperDef.setSource(source);
|
||||||
|
urlPathHelperDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||||
|
parserContext.getRegistry().registerBeanDefinition(URL_PATH_HELPER_BEAN_NAME, urlPathHelperDef);
|
||||||
|
parserContext.registerComponent(new BeanComponentDefinition(urlPathHelperDef, URL_PATH_HELPER_BEAN_NAME));
|
||||||
|
}
|
||||||
|
return new RuntimeBeanReference(URL_PATH_HELPER_BEAN_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an alias to an existing well-known name or registers a new instance of a {@link PathMatcher}
|
||||||
|
* under that well-known name, unless already registered.
|
||||||
|
* @return a RuntimeBeanReference to this {@link PathMatcher} instance
|
||||||
|
* @since 3.2.17
|
||||||
|
*/
|
||||||
|
public static RuntimeBeanReference registerPathMatcher(RuntimeBeanReference pathMatcherRef,
|
||||||
|
ParserContext parserContext, Object source) {
|
||||||
|
|
||||||
|
if (pathMatcherRef != null) {
|
||||||
|
if (parserContext.getRegistry().isAlias(PATH_MATCHER_BEAN_NAME)) {
|
||||||
|
parserContext.getRegistry().removeAlias(PATH_MATCHER_BEAN_NAME);
|
||||||
|
}
|
||||||
|
parserContext.getRegistry().registerAlias(pathMatcherRef.getBeanName(), PATH_MATCHER_BEAN_NAME);
|
||||||
|
}
|
||||||
|
else if (!parserContext.getRegistry().isAlias(PATH_MATCHER_BEAN_NAME)
|
||||||
|
&& !parserContext.getRegistry().containsBeanDefinition(PATH_MATCHER_BEAN_NAME)) {
|
||||||
|
RootBeanDefinition pathMatcherDef = new RootBeanDefinition(AntPathMatcher.class);
|
||||||
|
pathMatcherDef.setSource(source);
|
||||||
|
pathMatcherDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||||
|
parserContext.getRegistry().registerBeanDefinition(PATH_MATCHER_BEAN_NAME, pathMatcherDef);
|
||||||
|
parserContext.registerComponent(new BeanComponentDefinition(pathMatcherDef, PATH_MATCHER_BEAN_NAME));
|
||||||
|
}
|
||||||
|
return new RuntimeBeanReference(PATH_MATCHER_BEAN_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Registers an {@link HttpRequestHandlerAdapter} under a well-known
|
* Registers an {@link HttpRequestHandlerAdapter} under a well-known
|
||||||
* name unless already registered.
|
* name unless already registered.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -22,6 +22,7 @@ import java.util.Map;
|
||||||
import org.w3c.dom.Element;
|
import org.w3c.dom.Element;
|
||||||
|
|
||||||
import org.springframework.beans.factory.config.BeanDefinition;
|
import org.springframework.beans.factory.config.BeanDefinition;
|
||||||
|
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||||
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
import org.springframework.beans.factory.parsing.BeanComponentDefinition;
|
||||||
import org.springframework.beans.factory.support.ManagedList;
|
import org.springframework.beans.factory.support.ManagedList;
|
||||||
import org.springframework.beans.factory.support.ManagedMap;
|
import org.springframework.beans.factory.support.ManagedMap;
|
||||||
|
@ -62,10 +63,15 @@ class ResourcesBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
}
|
}
|
||||||
urlMap.put(resourceRequestPath, resourceHandlerName);
|
urlMap.put(resourceRequestPath, resourceHandlerName);
|
||||||
|
|
||||||
|
RuntimeBeanReference pathMatcherRef = MvcNamespaceUtils.registerPathMatcher(null, parserContext, source);
|
||||||
|
RuntimeBeanReference pathHelperRef = MvcNamespaceUtils.registerUrlPathHelper(null, parserContext, source);
|
||||||
|
|
||||||
RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
|
RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
|
||||||
handlerMappingDef.setSource(source);
|
handlerMappingDef.setSource(source);
|
||||||
handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||||
handlerMappingDef.getPropertyValues().add("urlMap", urlMap);
|
handlerMappingDef.getPropertyValues().add("urlMap", urlMap);
|
||||||
|
handlerMappingDef.getPropertyValues().add("pathMatcher", pathMatcherRef);
|
||||||
|
handlerMappingDef.getPropertyValues().add("urlPathHelper", pathHelperRef);
|
||||||
|
|
||||||
String order = element.getAttribute("order");
|
String order = element.getAttribute("order");
|
||||||
// use a default of near-lowest precedence, still allowing for even lower precedence in other mappings
|
// use a default of near-lowest precedence, still allowing for even lower precedence in other mappings
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -76,6 +76,10 @@ class ViewControllerBeanDefinitionParser implements BeanDefinitionParser {
|
||||||
RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
|
RootBeanDefinition handlerMappingDef = new RootBeanDefinition(SimpleUrlHandlerMapping.class);
|
||||||
handlerMappingDef.setSource(source);
|
handlerMappingDef.setSource(source);
|
||||||
handlerMappingDef.getPropertyValues().add("order", "1");
|
handlerMappingDef.getPropertyValues().add("order", "1");
|
||||||
|
handlerMappingDef.getPropertyValues().add("pathMatcher",
|
||||||
|
MvcNamespaceUtils.registerPathMatcher(null, parserContext, source));
|
||||||
|
handlerMappingDef.getPropertyValues().add("urlPathHelper",
|
||||||
|
MvcNamespaceUtils.registerUrlPathHelper(null, parserContext, source));
|
||||||
handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
handlerMappingDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
|
||||||
parserContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef);
|
parserContext.getRegistry().registerBeanDefinition(HANDLER_MAPPING_BEAN_NAME, handlerMappingDef);
|
||||||
parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, HANDLER_MAPPING_BEAN_NAME));
|
parserContext.registerComponent(new BeanComponentDefinition(handlerMappingDef, HANDLER_MAPPING_BEAN_NAME));
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2015 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -67,6 +67,11 @@ public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
|
||||||
this.configurers.configureAsyncSupport(configurer);
|
this.configurers.configureAsyncSupport(configurer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configurePathMatch(PathMatchConfigurer configurer) {
|
||||||
|
this.configurers.configurePathMatch(configurer);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void addViewControllers(ViewControllerRegistry registry) {
|
protected void addViewControllers(ViewControllerRegistry registry) {
|
||||||
this.configurers.addViewControllers(registry);
|
this.configurers.addViewControllers(registry);
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2002-2016 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.PathMatcher;
|
||||||
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps with configuring HandlerMappings path matching options such as trailing
|
||||||
|
* slash match, suffix registration, path matcher and path helper.
|
||||||
|
*
|
||||||
|
* <p>Configured path matcher and path helper instances are shared for:
|
||||||
|
* <ul>
|
||||||
|
* <li>RequestMappings</li>
|
||||||
|
* <li>ViewControllerMappings</li>
|
||||||
|
* <li>ResourcesMappings</li>
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @author Brian Clozel
|
||||||
|
* @since 3.2.17
|
||||||
|
* @see org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
|
||||||
|
* @see org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
|
||||||
|
*/
|
||||||
|
public class PathMatchConfigurer {
|
||||||
|
|
||||||
|
private Boolean suffixPatternMatch;
|
||||||
|
|
||||||
|
private Boolean trailingSlashMatch;
|
||||||
|
|
||||||
|
private Boolean registeredSuffixPatternMatch;
|
||||||
|
|
||||||
|
private UrlPathHelper urlPathHelper;
|
||||||
|
|
||||||
|
private PathMatcher pathMatcher;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to use suffix pattern match (".*") when matching patterns to
|
||||||
|
* requests. If enabled a method mapped to "/users" also matches to "/users.*".
|
||||||
|
* <p>By default this is set to {@code true}.
|
||||||
|
* @see #registeredSuffixPatternMatch
|
||||||
|
*/
|
||||||
|
public PathMatchConfigurer setUseSuffixPatternMatch(Boolean suffixPatternMatch) {
|
||||||
|
this.suffixPatternMatch = suffixPatternMatch;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to match to URLs irrespective of the presence of a trailing slash.
|
||||||
|
* If enabled a method mapped to "/users" also matches to "/users/".
|
||||||
|
* <p>The default value is {@code true}.
|
||||||
|
*/
|
||||||
|
public PathMatchConfigurer setUseTrailingSlashMatch(Boolean trailingSlashMatch) {
|
||||||
|
this.trailingSlashMatch = trailingSlashMatch;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether suffix pattern matching should work only against path extensions
|
||||||
|
* explicitly registered when you
|
||||||
|
* {@link WebMvcConfigurer#configureContentNegotiation configure content
|
||||||
|
* negotiation}. This is generally recommended to reduce ambiguity and to
|
||||||
|
* avoid issues such as when a "." appears in the path for other reasons.
|
||||||
|
* <p>By default this is set to "false".
|
||||||
|
* @see WebMvcConfigurer#configureContentNegotiation
|
||||||
|
*/
|
||||||
|
public PathMatchConfigurer setUseRegisteredSuffixPatternMatch(
|
||||||
|
Boolean registeredSuffixPatternMatch) {
|
||||||
|
|
||||||
|
this.registeredSuffixPatternMatch = registeredSuffixPatternMatch;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the UrlPathHelper to use for resolution of lookup paths.
|
||||||
|
* <p>Use this to override the default UrlPathHelper with a custom subclass,
|
||||||
|
* or to share common UrlPathHelper settings across multiple HandlerMappings
|
||||||
|
* and MethodNameResolvers.
|
||||||
|
*/
|
||||||
|
public PathMatchConfigurer setUrlPathHelper(UrlPathHelper urlPathHelper) {
|
||||||
|
this.urlPathHelper = urlPathHelper;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the PathMatcher implementation to use for matching URL paths
|
||||||
|
* against registered URL patterns. Default is AntPathMatcher.
|
||||||
|
* @see org.springframework.util.AntPathMatcher
|
||||||
|
*/
|
||||||
|
public PathMatchConfigurer setPathMatcher(PathMatcher pathMatcher) {
|
||||||
|
this.pathMatcher = pathMatcher;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isUseSuffixPatternMatch() {
|
||||||
|
return this.suffixPatternMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isUseTrailingSlashMatch() {
|
||||||
|
return this.trailingSlashMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Boolean isUseRegisteredSuffixPatternMatch() {
|
||||||
|
return this.registeredSuffixPatternMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
public UrlPathHelper getUrlPathHelper() {
|
||||||
|
return this.urlPathHelper;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PathMatcher getPathMatcher() {
|
||||||
|
return this.pathMatcher;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2014 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -47,7 +47,9 @@ import org.springframework.http.converter.json.MappingJacksonHttpMessageConverte
|
||||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||||
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
|
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
|
||||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
import org.springframework.util.ClassUtils;
|
import org.springframework.util.ClassUtils;
|
||||||
|
import org.springframework.util.PathMatcher;
|
||||||
import org.springframework.validation.Errors;
|
import org.springframework.validation.Errors;
|
||||||
import org.springframework.validation.MessageCodesResolver;
|
import org.springframework.validation.MessageCodesResolver;
|
||||||
import org.springframework.validation.Validator;
|
import org.springframework.validation.Validator;
|
||||||
|
@ -75,6 +77,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExc
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
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.RequestMappingHandlerMapping;
|
||||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||||
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the main class providing the configuration behind the MVC Java config.
|
* This is the main class providing the configuration behind the MVC Java config.
|
||||||
|
@ -163,6 +166,8 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
|
|
||||||
private ContentNegotiationManager contentNegotiationManager;
|
private ContentNegotiationManager contentNegotiationManager;
|
||||||
|
|
||||||
|
private PathMatchConfigurer pathMatchConfigurer;
|
||||||
|
|
||||||
private List<HttpMessageConverter<?>> messageConverters;
|
private List<HttpMessageConverter<?>> messageConverters;
|
||||||
|
|
||||||
|
|
||||||
|
@ -191,6 +196,24 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
handlerMapping.setOrder(0);
|
handlerMapping.setOrder(0);
|
||||||
handlerMapping.setInterceptors(getInterceptors());
|
handlerMapping.setInterceptors(getInterceptors());
|
||||||
handlerMapping.setContentNegotiationManager(mvcContentNegotiationManager());
|
handlerMapping.setContentNegotiationManager(mvcContentNegotiationManager());
|
||||||
|
|
||||||
|
PathMatchConfigurer configurer = getPathMatchConfigurer();
|
||||||
|
if (configurer.isUseSuffixPatternMatch() != null) {
|
||||||
|
handlerMapping.setUseSuffixPatternMatch(configurer.isUseSuffixPatternMatch());
|
||||||
|
}
|
||||||
|
if (configurer.isUseRegisteredSuffixPatternMatch() != null) {
|
||||||
|
handlerMapping.setUseRegisteredSuffixPatternMatch(configurer.isUseRegisteredSuffixPatternMatch());
|
||||||
|
}
|
||||||
|
if (configurer.isUseTrailingSlashMatch() != null) {
|
||||||
|
handlerMapping.setUseTrailingSlashMatch(configurer.isUseTrailingSlashMatch());
|
||||||
|
}
|
||||||
|
if (configurer.getPathMatcher() != null) {
|
||||||
|
handlerMapping.setPathMatcher(configurer.getPathMatcher());
|
||||||
|
}
|
||||||
|
if (configurer.getUrlPathHelper() != null) {
|
||||||
|
handlerMapping.setUrlPathHelper(configurer.getUrlPathHelper());
|
||||||
|
}
|
||||||
|
|
||||||
return handlerMapping;
|
return handlerMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,6 +282,61 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
protected void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
|
protected void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Callback for building the {@link PathMatchConfigurer}.
|
||||||
|
* Delegates to {@link #configurePathMatch}.
|
||||||
|
* @since 3.2.17
|
||||||
|
*/
|
||||||
|
protected PathMatchConfigurer getPathMatchConfigurer() {
|
||||||
|
if (this.pathMatchConfigurer == null) {
|
||||||
|
this.pathMatchConfigurer = new PathMatchConfigurer();
|
||||||
|
configurePathMatch(this.pathMatchConfigurer);
|
||||||
|
}
|
||||||
|
return this.pathMatchConfigurer;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Override this method to configure path matching options.
|
||||||
|
* @see PathMatchConfigurer
|
||||||
|
* @since 3.2.17
|
||||||
|
*/
|
||||||
|
public void configurePathMatch(PathMatchConfigurer configurer) {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a global {@link PathMatcher} instance for path matching
|
||||||
|
* patterns in {@link HandlerMapping}s.
|
||||||
|
* This instance can be configured using the {@link PathMatchConfigurer}
|
||||||
|
* in {@link #configurePathMatch(PathMatchConfigurer)}.
|
||||||
|
* @since 3.2.17
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public PathMatcher mvcPathMatcher() {
|
||||||
|
if (getPathMatchConfigurer().getPathMatcher() != null) {
|
||||||
|
return getPathMatchConfigurer().getPathMatcher();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new AntPathMatcher();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a global {@link UrlPathHelper} instance for path matching
|
||||||
|
* patterns in {@link HandlerMapping}s.
|
||||||
|
* This instance can be configured using the {@link PathMatchConfigurer}
|
||||||
|
* in {@link #configurePathMatch(PathMatchConfigurer)}.
|
||||||
|
* @since 3.2.17
|
||||||
|
*/
|
||||||
|
@Bean
|
||||||
|
public UrlPathHelper mvcUrlPathHelper() {
|
||||||
|
if (getPathMatchConfigurer().getUrlPathHelper() != null) {
|
||||||
|
return getPathMatchConfigurer().getUrlPathHelper();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return new UrlPathHelper();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a handler mapping ordered at 1 to map URL paths directly to
|
* Return a handler mapping ordered at 1 to map URL paths directly to
|
||||||
* view names. To configure view controllers, override
|
* view names. To configure view controllers, override
|
||||||
|
@ -272,6 +350,8 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
|
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
|
||||||
handlerMapping = (handlerMapping != null ? handlerMapping : new EmptyHandlerMapping());
|
handlerMapping = (handlerMapping != null ? handlerMapping : new EmptyHandlerMapping());
|
||||||
handlerMapping.setInterceptors(getInterceptors());
|
handlerMapping.setInterceptors(getInterceptors());
|
||||||
|
handlerMapping.setPathMatcher(mvcPathMatcher());
|
||||||
|
handlerMapping.setUrlPathHelper(mvcUrlPathHelper());
|
||||||
return handlerMapping;
|
return handlerMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -305,7 +385,13 @@ public class WebMvcConfigurationSupport implements ApplicationContextAware, Serv
|
||||||
addResourceHandlers(registry);
|
addResourceHandlers(registry);
|
||||||
|
|
||||||
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
|
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
|
||||||
handlerMapping = (handlerMapping != null ? handlerMapping : new EmptyHandlerMapping());
|
if (handlerMapping != null) {
|
||||||
|
handlerMapping.setPathMatcher(mvcPathMatcher());
|
||||||
|
handlerMapping.setUrlPathHelper(mvcUrlPathHelper());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
handlerMapping = new EmptyHandlerMapping();
|
||||||
|
}
|
||||||
return handlerMapping;
|
return handlerMapping;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -79,6 +79,20 @@ public interface WebMvcConfigurer {
|
||||||
*/
|
*/
|
||||||
void configureAsyncSupport(AsyncSupportConfigurer configurer);
|
void configureAsyncSupport(AsyncSupportConfigurer configurer);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helps with configuring HandlerMappings path matching options such as trailing slash match,
|
||||||
|
* suffix registration, path matcher and path helper.
|
||||||
|
* Configured path matcher and path helper instances are shared for:
|
||||||
|
* <ul>
|
||||||
|
* <li>RequestMappings</li>
|
||||||
|
* <li>ViewControllerMappings</li>
|
||||||
|
* <li>ResourcesMappings</li>
|
||||||
|
* </ul>
|
||||||
|
* @since 3.2.17
|
||||||
|
*/
|
||||||
|
void configurePathMatch(PathMatchConfigurer configurer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add resolvers to support custom controller method argument types.
|
* Add resolvers to support custom controller method argument types.
|
||||||
* <p>This does not override the built-in support for resolving handler
|
* <p>This does not override the built-in support for resolving handler
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -71,6 +71,13 @@ public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {
|
||||||
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
|
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
* <p>This implementation is empty.
|
||||||
|
*/
|
||||||
|
public void configurePathMatch(PathMatchConfigurer configurer) {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
* <p>This implementation is empty.
|
* <p>This implementation is empty.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -61,6 +61,12 @@ class WebMvcConfigurerComposite implements WebMvcConfigurer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void configurePathMatch(PathMatchConfigurer configurer) {
|
||||||
|
for (WebMvcConfigurer delegate : this.delegates) {
|
||||||
|
delegate.configurePathMatch(configurer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
for (WebMvcConfigurer delegate : this.delegates) {
|
for (WebMvcConfigurer delegate : this.delegates) {
|
||||||
delegate.configureMessageConverters(converters);
|
delegate.configureMessageConverters(converters);
|
||||||
|
|
|
@ -21,6 +21,62 @@
|
||||||
</xsd:annotation>
|
</xsd:annotation>
|
||||||
<xsd:complexType>
|
<xsd:complexType>
|
||||||
<xsd:all minOccurs="0">
|
<xsd:all minOccurs="0">
|
||||||
|
<xsd:element name="path-matching" minOccurs="0">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
Configures the path matching part of the Spring MVC Controller programming model.
|
||||||
|
Like annotation-driven, code-based alternatives are also documented in EnableWebMvc javadoc.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="suffix-pattern" type="xsd:boolean">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
Whether to use suffix pattern match (".*") when matching patterns to requests. If enabled
|
||||||
|
a method mapped to "/users" also matches to "/users.*".
|
||||||
|
The default value is true.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="trailing-slash" type="xsd:boolean">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
Whether to match to URLs irrespective of the presence of a trailing slash.
|
||||||
|
If enabled a method mapped to "/users" also matches to "/users/".
|
||||||
|
The default value is true.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="registered-suffixes-only" type="xsd:boolean">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
Whether suffix pattern matching should work only against path extensions
|
||||||
|
explicitly registered when you configure content negotiation.
|
||||||
|
This is generally recommended to reduce ambiguity and to
|
||||||
|
avoid issues such as when a "." appears in the path for other reasons.
|
||||||
|
The default value is false.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="path-helper" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The bean name of the UrlPathHelper to use for resolution of lookup paths.
|
||||||
|
Use this to override the default UrlPathHelper with a custom subclass, or to share common UrlPathHelper settings across
|
||||||
|
multiple HandlerMappings and MethodNameResolvers.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
<xsd:attribute name="path-matcher" type="xsd:string">
|
||||||
|
<xsd:annotation>
|
||||||
|
<xsd:documentation><![CDATA[
|
||||||
|
The bean name of the PathMatcher implementation to use for matching URL paths against registered URL patterns.
|
||||||
|
Default is AntPathMatcher.
|
||||||
|
]]></xsd:documentation>
|
||||||
|
</xsd:annotation>
|
||||||
|
</xsd:attribute>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
<xsd:element name="message-converters" minOccurs="0">
|
<xsd:element name="message-converters" minOccurs="0">
|
||||||
<xsd:annotation>
|
<xsd:annotation>
|
||||||
<xsd:documentation><![CDATA[
|
<xsd:documentation><![CDATA[
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -16,11 +16,14 @@
|
||||||
package org.springframework.web.servlet.config;
|
package org.springframework.web.servlet.config;
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.beans.DirectFieldAccessor;
|
import org.springframework.beans.DirectFieldAccessor;
|
||||||
|
@ -30,6 +33,7 @@ import org.springframework.core.io.ClassPathResource;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.converter.ResourceHttpMessageConverter;
|
import org.springframework.http.converter.ResourceHttpMessageConverter;
|
||||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
import org.springframework.validation.MessageCodesResolver;
|
import org.springframework.validation.MessageCodesResolver;
|
||||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||||
import org.springframework.web.bind.support.WebArgumentResolver;
|
import org.springframework.web.bind.support.WebArgumentResolver;
|
||||||
|
@ -42,7 +46,9 @@ import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
|
import org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||||
|
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ServletWebArgumentResolverAdapter;
|
import org.springframework.web.servlet.mvc.method.annotation.ServletWebArgumentResolverAdapter;
|
||||||
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test fixture for the configuration in mvc-config-annotation-driven.xml.
|
* Test fixture for the configuration in mvc-config-annotation-driven.xml.
|
||||||
|
@ -70,6 +76,21 @@ public class AnnotationDrivenBeanDefinitionParserTests {
|
||||||
assertEquals(false, new DirectFieldAccessor(adapter).getPropertyValue("ignoreDefaultModelOnRedirect"));
|
assertEquals(false, new DirectFieldAccessor(adapter).getPropertyValue("ignoreDefaultModelOnRedirect"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPathMatchingConfiguration() {
|
||||||
|
loadBeanDefinitions("mvc-config-path-matching.xml");
|
||||||
|
RequestMappingHandlerMapping hm = this.appContext.getBean(RequestMappingHandlerMapping.class);
|
||||||
|
assertNotNull(hm);
|
||||||
|
assertTrue(hm.useSuffixPatternMatch());
|
||||||
|
assertFalse(hm.useTrailingSlashMatch());
|
||||||
|
assertTrue(hm.useRegisteredSuffixPatternMatch());
|
||||||
|
assertThat(hm.getUrlPathHelper(), Matchers.instanceOf(TestPathHelper.class));
|
||||||
|
assertThat(hm.getPathMatcher(), Matchers.instanceOf(TestPathMatcher.class));
|
||||||
|
List<String> fileExtensions = hm.getContentNegotiationManager().getAllFileExtensions();
|
||||||
|
assertThat(fileExtensions, Matchers.contains("xml"));
|
||||||
|
assertThat(fileExtensions, Matchers.hasSize(1));
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testMessageConverters() {
|
public void testMessageConverters() {
|
||||||
loadBeanDefinitions("mvc-config-message-converters.xml");
|
loadBeanDefinitions("mvc-config-message-converters.xml");
|
||||||
|
@ -198,3 +219,7 @@ class TestMessageCodesResolver implements MessageCodesResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class TestPathMatcher extends AntPathMatcher { }
|
||||||
|
|
||||||
|
class TestPathHelper extends UrlPathHelper { }
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -20,9 +20,11 @@ import java.lang.annotation.Retention;
|
||||||
import java.lang.annotation.RetentionPolicy;
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Comparator;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.RequestDispatcher;
|
import javax.servlet.RequestDispatcher;
|
||||||
import javax.validation.constraints.NotNull;
|
import javax.validation.constraints.NotNull;
|
||||||
|
@ -47,6 +49,7 @@ import org.springframework.mock.web.test.MockRequestDispatcher;
|
||||||
import org.springframework.mock.web.test.MockServletContext;
|
import org.springframework.mock.web.test.MockServletContext;
|
||||||
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
|
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.util.PathMatcher;
|
||||||
import org.springframework.validation.BindingResult;
|
import org.springframework.validation.BindingResult;
|
||||||
import org.springframework.validation.Errors;
|
import org.springframework.validation.Errors;
|
||||||
import org.springframework.validation.Validator;
|
import org.springframework.validation.Validator;
|
||||||
|
@ -79,6 +82,7 @@ import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandl
|
||||||
import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
|
import org.springframework.web.servlet.resource.DefaultServletHttpRequestHandler;
|
||||||
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
|
import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
|
||||||
import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
|
import org.springframework.web.servlet.theme.ThemeChangeInterceptor;
|
||||||
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
@ -89,6 +93,10 @@ import static org.junit.Assert.*;
|
||||||
*/
|
*/
|
||||||
public class MvcNamespaceTests {
|
public class MvcNamespaceTests {
|
||||||
|
|
||||||
|
private static final String VIEWCONTROLLER_BEAN_NAME =
|
||||||
|
"org.springframework.web.servlet.config.viewControllerHandlerMapping";
|
||||||
|
|
||||||
|
|
||||||
private GenericWebApplicationContext appContext;
|
private GenericWebApplicationContext appContext;
|
||||||
|
|
||||||
private TestController handler;
|
private TestController handler;
|
||||||
|
@ -234,7 +242,7 @@ public class MvcNamespaceTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testResources() throws Exception {
|
public void testResources() throws Exception {
|
||||||
loadBeanDefinitions("mvc-config-resources.xml", 5);
|
loadBeanDefinitions("mvc-config-resources.xml", 7);
|
||||||
|
|
||||||
HttpRequestHandlerAdapter adapter = appContext.getBean(HttpRequestHandlerAdapter.class);
|
HttpRequestHandlerAdapter adapter = appContext.getBean(HttpRequestHandlerAdapter.class);
|
||||||
assertNotNull(adapter);
|
assertNotNull(adapter);
|
||||||
|
@ -267,7 +275,7 @@ public class MvcNamespaceTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testResourcesWithOptionalAttributes() throws Exception {
|
public void testResourcesWithOptionalAttributes() throws Exception {
|
||||||
loadBeanDefinitions("mvc-config-resources-optional-attrs.xml", 5);
|
loadBeanDefinitions("mvc-config-resources-optional-attrs.xml", 7);
|
||||||
|
|
||||||
SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class);
|
SimpleUrlHandlerMapping mapping = appContext.getBean(SimpleUrlHandlerMapping.class);
|
||||||
assertNotNull(mapping);
|
assertNotNull(mapping);
|
||||||
|
@ -349,7 +357,7 @@ public class MvcNamespaceTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testViewControllers() throws Exception {
|
public void testViewControllers() throws Exception {
|
||||||
loadBeanDefinitions("mvc-config-view-controllers.xml", 15);
|
loadBeanDefinitions("mvc-config-view-controllers.xml", 17);
|
||||||
|
|
||||||
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
|
RequestMappingHandlerMapping mapping = appContext.getBean(RequestMappingHandlerMapping.class);
|
||||||
assertNotNull(mapping);
|
assertNotNull(mapping);
|
||||||
|
@ -409,7 +417,7 @@ public class MvcNamespaceTests {
|
||||||
/** WebSphere gives trailing servlet path slashes by default!! */
|
/** WebSphere gives trailing servlet path slashes by default!! */
|
||||||
@Test
|
@Test
|
||||||
public void testViewControllersOnWebSphere() throws Exception {
|
public void testViewControllersOnWebSphere() throws Exception {
|
||||||
loadBeanDefinitions("mvc-config-view-controllers.xml", 15);
|
loadBeanDefinitions("mvc-config-view-controllers.xml", 17);
|
||||||
|
|
||||||
SimpleUrlHandlerMapping mapping2 = appContext.getBean(SimpleUrlHandlerMapping.class);
|
SimpleUrlHandlerMapping mapping2 = appContext.getBean(SimpleUrlHandlerMapping.class);
|
||||||
SimpleControllerHandlerAdapter adapter = appContext.getBean(SimpleControllerHandlerAdapter.class);
|
SimpleControllerHandlerAdapter adapter = appContext.getBean(SimpleControllerHandlerAdapter.class);
|
||||||
|
@ -453,7 +461,7 @@ public class MvcNamespaceTests {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testViewControllersDefaultConfig() {
|
public void testViewControllersDefaultConfig() {
|
||||||
loadBeanDefinitions("mvc-config-view-controllers-minimal.xml", 4);
|
loadBeanDefinitions("mvc-config-view-controllers-minimal.xml", 6);
|
||||||
|
|
||||||
BeanNameUrlHandlerMapping beanNameMapping = appContext.getBean(BeanNameUrlHandlerMapping.class);
|
BeanNameUrlHandlerMapping beanNameMapping = appContext.getBean(BeanNameUrlHandlerMapping.class);
|
||||||
assertNotNull(beanNameMapping);
|
assertNotNull(beanNameMapping);
|
||||||
|
@ -492,6 +500,27 @@ public class MvcNamespaceTests {
|
||||||
assertEquals(1, deferredResultInterceptors.length);
|
assertEquals(1, deferredResultInterceptors.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testPathMatchingHandlerMappings() throws Exception {
|
||||||
|
loadBeanDefinitions("mvc-config-path-matching-mappings.xml", 19);
|
||||||
|
|
||||||
|
RequestMappingHandlerMapping requestMapping = appContext.getBean(RequestMappingHandlerMapping.class);
|
||||||
|
assertNotNull(requestMapping);
|
||||||
|
assertEquals(TestPathHelper.class, requestMapping.getUrlPathHelper().getClass());
|
||||||
|
assertEquals(TestPathMatcher.class, requestMapping.getPathMatcher().getClass());
|
||||||
|
|
||||||
|
SimpleUrlHandlerMapping viewController = appContext.getBean(VIEWCONTROLLER_BEAN_NAME, SimpleUrlHandlerMapping.class);
|
||||||
|
assertNotNull(viewController);
|
||||||
|
assertEquals(TestPathHelper.class, viewController.getUrlPathHelper().getClass());
|
||||||
|
assertEquals(TestPathMatcher.class, viewController.getPathMatcher().getClass());
|
||||||
|
|
||||||
|
for (SimpleUrlHandlerMapping handlerMapping : appContext.getBeansOfType(SimpleUrlHandlerMapping.class).values()) {
|
||||||
|
assertNotNull(handlerMapping);
|
||||||
|
assertEquals(TestPathHelper.class, handlerMapping.getUrlPathHelper().getClass());
|
||||||
|
assertEquals(TestPathMatcher.class, handlerMapping.getPathMatcher().getClass());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private void loadBeanDefinitions(String fileName, int expectedBeanCount) {
|
private void loadBeanDefinitions(String fileName, int expectedBeanCount) {
|
||||||
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext);
|
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(appContext);
|
||||||
|
@ -564,4 +593,45 @@ public class MvcNamespaceTests {
|
||||||
|
|
||||||
public static class TestDeferredResultProcessingInterceptor extends DeferredResultProcessingInterceptorAdapter { }
|
public static class TestDeferredResultProcessingInterceptor extends DeferredResultProcessingInterceptorAdapter { }
|
||||||
|
|
||||||
|
public static class TestPathMatcher implements PathMatcher {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isPattern(String path) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean match(String pattern, String path) {
|
||||||
|
return path.matches(pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchStart(String pattern, String path) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String extractPathWithinPattern(String pattern, String path) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, String> extractUriTemplateVariables(String pattern, String path) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Comparator<String> getPatternComparator(String path) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String combine(String pattern1, String pattern2) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class TestPathHelper extends UrlPathHelper {
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -30,6 +30,7 @@ import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.format.support.FormattingConversionService;
|
import org.springframework.format.support.FormattingConversionService;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||||
|
import org.springframework.util.PathMatcher;
|
||||||
import org.springframework.validation.DefaultMessageCodesResolver;
|
import org.springframework.validation.DefaultMessageCodesResolver;
|
||||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||||
|
@ -40,7 +41,9 @@ import org.springframework.web.servlet.handler.HandlerExceptionResolverComposite
|
||||||
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
import org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
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;
|
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||||
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import static org.mockito.BDDMockito.*;
|
import static org.mockito.BDDMockito.*;
|
||||||
|
@ -178,4 +181,30 @@ public class DelegatingWebMvcConfigurationTests {
|
||||||
assertEquals("Only one custom converter is expected", 1, composite.getExceptionResolvers().size());
|
assertEquals("Only one custom converter is expected", 1, composite.getExceptionResolvers().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void configurePathMatch() throws Exception {
|
||||||
|
final PathMatcher pathMatcher = mock(PathMatcher.class);
|
||||||
|
final UrlPathHelper pathHelper = mock(UrlPathHelper.class);
|
||||||
|
|
||||||
|
List<WebMvcConfigurer> configurers = new ArrayList<WebMvcConfigurer>();
|
||||||
|
configurers.add(new WebMvcConfigurerAdapter() {
|
||||||
|
@Override
|
||||||
|
public void configurePathMatch(PathMatchConfigurer configurer) {
|
||||||
|
configurer.setUseRegisteredSuffixPatternMatch(true)
|
||||||
|
.setUseTrailingSlashMatch(false)
|
||||||
|
.setUrlPathHelper(pathHelper)
|
||||||
|
.setPathMatcher(pathMatcher);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
delegatingConfig.setConfigurers(configurers);
|
||||||
|
|
||||||
|
RequestMappingHandlerMapping handlerMapping = delegatingConfig.requestMappingHandlerMapping();
|
||||||
|
assertNotNull(handlerMapping);
|
||||||
|
assertTrue(handlerMapping.useRegisteredSuffixPatternMatch());
|
||||||
|
assertTrue(handlerMapping.useSuffixPatternMatch());
|
||||||
|
assertFalse(handlerMapping.useTrailingSlashMatch());
|
||||||
|
assertSame(pathHelper, handlerMapping.getUrlPathHelper());
|
||||||
|
assertSame(pathMatcher, handlerMapping.getPathMatcher());
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2013 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -35,6 +35,7 @@ import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||||
import org.springframework.mock.web.test.MockServletContext;
|
import org.springframework.mock.web.test.MockServletContext;
|
||||||
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
|
import org.springframework.scheduling.concurrent.ConcurrentTaskExecutor;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
import org.springframework.validation.BeanPropertyBindingResult;
|
import org.springframework.validation.BeanPropertyBindingResult;
|
||||||
import org.springframework.validation.DefaultMessageCodesResolver;
|
import org.springframework.validation.DefaultMessageCodesResolver;
|
||||||
import org.springframework.validation.Errors;
|
import org.springframework.validation.Errors;
|
||||||
|
@ -62,6 +63,7 @@ import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
|
||||||
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
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.RequestMappingHandlerMapping;
|
||||||
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A test fixture with a sub-class of {@link WebMvcConfigurationSupport} that
|
* A test fixture with a sub-class of {@link WebMvcConfigurationSupport} that
|
||||||
|
@ -92,6 +94,10 @@ public class WebMvcConfigurationSupportExtensionTests {
|
||||||
RequestMappingHandlerMapping rmHandlerMapping = webConfig.requestMappingHandlerMapping();
|
RequestMappingHandlerMapping rmHandlerMapping = webConfig.requestMappingHandlerMapping();
|
||||||
rmHandlerMapping.setApplicationContext(webAppContext);
|
rmHandlerMapping.setApplicationContext(webAppContext);
|
||||||
rmHandlerMapping.afterPropertiesSet();
|
rmHandlerMapping.afterPropertiesSet();
|
||||||
|
|
||||||
|
assertEquals(TestPathHelper.class, rmHandlerMapping.getUrlPathHelper().getClass());
|
||||||
|
assertEquals(TestPathMatcher.class, rmHandlerMapping.getPathMatcher().getClass());
|
||||||
|
|
||||||
HandlerExecutionChain chain = rmHandlerMapping.getHandler(new MockHttpServletRequest("GET", "/"));
|
HandlerExecutionChain chain = rmHandlerMapping.getHandler(new MockHttpServletRequest("GET", "/"));
|
||||||
assertNotNull(chain.getInterceptors());
|
assertNotNull(chain.getInterceptors());
|
||||||
assertEquals(2, chain.getInterceptors().length);
|
assertEquals(2, chain.getInterceptors().length);
|
||||||
|
@ -102,6 +108,8 @@ public class WebMvcConfigurationSupportExtensionTests {
|
||||||
handlerMapping.setApplicationContext(webAppContext);
|
handlerMapping.setApplicationContext(webAppContext);
|
||||||
assertNotNull(handlerMapping);
|
assertNotNull(handlerMapping);
|
||||||
assertEquals(1, handlerMapping.getOrder());
|
assertEquals(1, handlerMapping.getOrder());
|
||||||
|
assertEquals(TestPathHelper.class, handlerMapping.getUrlPathHelper().getClass());
|
||||||
|
assertEquals(TestPathMatcher.class, handlerMapping.getPathMatcher().getClass());
|
||||||
HandlerExecutionChain handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/path"));
|
HandlerExecutionChain handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/path"));
|
||||||
assertNotNull(handler.getHandler());
|
assertNotNull(handler.getHandler());
|
||||||
|
|
||||||
|
@ -109,6 +117,8 @@ public class WebMvcConfigurationSupportExtensionTests {
|
||||||
handlerMapping.setApplicationContext(webAppContext);
|
handlerMapping.setApplicationContext(webAppContext);
|
||||||
assertNotNull(handlerMapping);
|
assertNotNull(handlerMapping);
|
||||||
assertEquals(Integer.MAX_VALUE-1, handlerMapping.getOrder());
|
assertEquals(Integer.MAX_VALUE-1, handlerMapping.getOrder());
|
||||||
|
assertEquals(TestPathHelper.class, handlerMapping.getUrlPathHelper().getClass());
|
||||||
|
assertEquals(TestPathMatcher.class, handlerMapping.getPathMatcher().getClass());
|
||||||
handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/resources/foo.gif"));
|
handler = handlerMapping.getHandler(new MockHttpServletRequest("GET", "/resources/foo.gif"));
|
||||||
assertNotNull(handler.getHandler());
|
assertNotNull(handler.getHandler());
|
||||||
|
|
||||||
|
@ -280,6 +290,12 @@ public class WebMvcConfigurationSupportExtensionTests {
|
||||||
registry.addInterceptor(new LocaleChangeInterceptor());
|
registry.addInterceptor(new LocaleChangeInterceptor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configurePathMatch(PathMatchConfigurer configurer) {
|
||||||
|
configurer.setPathMatcher(new TestPathMatcher());
|
||||||
|
configurer.setUrlPathHelper(new TestPathHelper());
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
@Override
|
@Override
|
||||||
public MessageCodesResolver getMessageCodesResolver() {
|
public MessageCodesResolver getMessageCodesResolver() {
|
||||||
|
@ -308,4 +324,8 @@ public class WebMvcConfigurationSupportExtensionTests {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class TestPathHelper extends UrlPathHelper {}
|
||||||
|
|
||||||
|
private class TestPathMatcher extends AntPathMatcher {}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2002-2012 the original author or authors.
|
* Copyright 2002-2016 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -27,16 +27,23 @@ import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
import org.springframework.core.convert.ConversionService;
|
import org.springframework.core.convert.ConversionService;
|
||||||
import org.springframework.format.support.FormattingConversionService;
|
import org.springframework.format.support.FormattingConversionService;
|
||||||
import org.springframework.http.converter.HttpMessageConverter;
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||||
import org.springframework.mock.web.test.MockServletContext;
|
import org.springframework.mock.web.test.MockServletContext;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
import org.springframework.util.PathMatcher;
|
||||||
import org.springframework.validation.Validator;
|
import org.springframework.validation.Validator;
|
||||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
|
||||||
|
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
|
||||||
import org.springframework.web.context.support.StaticWebApplicationContext;
|
import org.springframework.web.context.support.StaticWebApplicationContext;
|
||||||
import org.springframework.web.servlet.HandlerExceptionResolver;
|
import org.springframework.web.servlet.HandlerExceptionResolver;
|
||||||
import org.springframework.web.servlet.HandlerExecutionChain;
|
import org.springframework.web.servlet.HandlerExecutionChain;
|
||||||
|
@ -49,6 +56,7 @@ import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExc
|
||||||
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
|
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.RequestMappingHandlerMapping;
|
||||||
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
import org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver;
|
||||||
|
import org.springframework.web.util.UrlPathHelper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A test fixture with an {@link WebMvcConfigurationSupport} instance.
|
* A test fixture with an {@link WebMvcConfigurationSupport} instance.
|
||||||
|
@ -163,6 +171,32 @@ public class WebMvcConfigurationSupportTests {
|
||||||
assertNotNull(eher.getApplicationContext());
|
assertNotNull(eher.getApplicationContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void defaultPathMatchConfiguration() throws Exception {
|
||||||
|
AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
|
||||||
|
context.setServletContext(new MockServletContext());
|
||||||
|
context.register(WebConfig.class);
|
||||||
|
context.refresh();
|
||||||
|
|
||||||
|
UrlPathHelper urlPathHelper = context.getBean(UrlPathHelper.class);
|
||||||
|
PathMatcher pathMatcher = context.getBean(PathMatcher.class);
|
||||||
|
|
||||||
|
assertNotNull(urlPathHelper);
|
||||||
|
assertNotNull(pathMatcher);
|
||||||
|
assertEquals(AntPathMatcher.class, pathMatcher.getClass());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@EnableWebMvc
|
||||||
|
@Configuration
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
static class WebConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TestController testController() {
|
||||||
|
return new TestController();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Controller
|
@Controller
|
||||||
private static class TestController {
|
private static class TestController {
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
|
||||||
|
|
||||||
|
<mvc:resources mapping="/resources/**" location="/, classpath:/META-INF/" />
|
||||||
|
|
||||||
|
<mvc:annotation-driven>
|
||||||
|
<mvc:path-matching
|
||||||
|
path-helper="pathHelper"
|
||||||
|
path-matcher="pathMatcher" />
|
||||||
|
</mvc:annotation-driven>
|
||||||
|
|
||||||
|
<mvc:view-controller path="/" view-name="home"/>
|
||||||
|
<mvc:view-controller path="/test" view-name="test"/>
|
||||||
|
|
||||||
|
<bean id="pathMatcher" class="org.springframework.web.servlet.config.MvcNamespaceTests$TestPathMatcher" />
|
||||||
|
<bean id="pathHelper" class="org.springframework.web.servlet.config.MvcNamespaceTests$TestPathHelper" />
|
||||||
|
|
||||||
|
</beans>
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
|
||||||
|
|
||||||
|
<mvc:annotation-driven content-negotiation-manager="contentNegotiationManager">
|
||||||
|
<mvc:path-matching
|
||||||
|
suffix-pattern="true"
|
||||||
|
trailing-slash="false"
|
||||||
|
registered-suffixes-only="true"
|
||||||
|
path-helper="pathHelper"
|
||||||
|
path-matcher="pathMatcher" />
|
||||||
|
</mvc:annotation-driven>
|
||||||
|
|
||||||
|
<bean id="pathMatcher" class="org.springframework.web.servlet.config.TestPathMatcher" />
|
||||||
|
<bean id="pathHelper" class="org.springframework.web.servlet.config.TestPathHelper" />
|
||||||
|
<bean id="contentNegotiationManager" class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
|
||||||
|
<property name="mediaTypes">
|
||||||
|
<value>
|
||||||
|
xml=application/rss+xml
|
||||||
|
</value>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</beans>
|
Loading…
Reference in New Issue