From 82ca2011e34d6cae9f70baf3027a606835702a86 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Wed, 13 Jul 2016 15:14:42 +0200 Subject: [PATCH] Configurable UrlPathHelper in PathExtensionContentNegotiationStrategy This commit also aligns ResourceUrlProvider's and RequestMappingInfo's UrlPathHelper setter/getter signatures. Issue: SPR-14454 (cherry picked from commit 5c3c0f7) --- ...thExtensionContentNegotiationStrategy.java | 34 +++++++------- .../mvc/method/RequestMappingInfo.java | 45 +++++++++++++++---- .../RequestMappingHandlerMapping.java | 2 +- .../resource/ResourceUrlEncodingFilter.java | 8 ++-- .../servlet/resource/ResourceUrlProvider.java | 26 +++++++---- 5 files changed, 80 insertions(+), 35 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java b/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java index 9f0c26727ad..9dc1c0e174d 100644 --- a/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java +++ b/spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java @@ -51,42 +51,46 @@ import org.springframework.web.util.WebUtils; * @author Rossen Stoyanchev * @since 3.2 */ -public class PathExtensionContentNegotiationStrategy - extends AbstractMappingContentNegotiationStrategy { - - private static final Log logger = LogFactory.getLog(PathExtensionContentNegotiationStrategy.class); +public class PathExtensionContentNegotiationStrategy extends AbstractMappingContentNegotiationStrategy { private static final boolean JAF_PRESENT = ClassUtils.isPresent("javax.activation.FileTypeMap", PathExtensionContentNegotiationStrategy.class.getClassLoader()); - private static final UrlPathHelper PATH_HELPER = new UrlPathHelper(); - - static { - PATH_HELPER.setUrlDecode(false); - } + private static final Log logger = LogFactory.getLog(PathExtensionContentNegotiationStrategy.class); + private UrlPathHelper urlPathHelper = new UrlPathHelper(); private boolean useJaf = true; private boolean ignoreUnknownExtensions = true; + /** + * Create an instance without any mappings to start with. Mappings may be added + * later on if any extensions are resolved through the Java Activation framework. + */ + public PathExtensionContentNegotiationStrategy() { + this(null); + } + /** * Create an instance with the given map of file extensions and media types. */ public PathExtensionContentNegotiationStrategy(Map mediaTypes) { super(mediaTypes); + this.urlPathHelper.setUrlDecode(false); } + /** - * Create an instance without any mappings to start with. Mappings may be added - * later on if any extensions are resolved through the Java Activation framework. + * Configure a {@code UrlPathHelper} to use in {@link #getMediaTypeKey} + * in order to derive the lookup path for a target request URL path. + * @since 4.2.8 */ - public PathExtensionContentNegotiationStrategy() { - super(null); + public void setUrlPathHelper(UrlPathHelper urlPathHelper) { + this.urlPathHelper = urlPathHelper; } - /** * Whether to use the Java Activation Framework to look up file extensions. *

By default this is set to "true" but depends on JAF being present. @@ -112,7 +116,7 @@ public class PathExtensionContentNegotiationStrategy logger.warn("An HttpServletRequest is required to determine the media type key"); return null; } - String path = PATH_HELPER.getLookupPathForRequest(request); + String path = this.urlPathHelper.getLookupPathForRequest(request); String filename = WebUtils.extractFullFilenameFromUrlPath(path); String extension = StringUtils.getFilenameExtension(filename); return (StringUtils.hasText(extension)) ? extension.toLowerCase(Locale.ENGLISH) : null; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java index 395ecb9cc31..5131ade89a5 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java @@ -537,13 +537,25 @@ public final class RequestMappingInfo implements RequestConditionBy default this is not set. + * @deprecated as of Spring 4.2.8, in favor of {@link #setUrlPathHelper} */ + @Deprecated public void setPathHelper(UrlPathHelper pathHelper) { this.urlPathHelper = pathHelper; } + /** + * Set a custom UrlPathHelper to use for the PatternsRequestCondition. + *

By default this is not set. + * @since 4.2.8 + */ + public void setUrlPathHelper(UrlPathHelper urlPathHelper) { + this.urlPathHelper = urlPathHelper; + } + + /** + * Return a custom UrlPathHelper to use for the PatternsRequestCondition, if any. + */ public UrlPathHelper getUrlPathHelper() { return this.urlPathHelper; } @@ -556,24 +568,30 @@ public final class RequestMappingInfo implements RequestConditionBy default this is set to 'true'. */ public void setTrailingSlashMatch(boolean trailingSlashMatch) { this.trailingSlashMatch = trailingSlashMatch; } + /** + * Return whether to apply trailing slash matching in PatternsRequestCondition. + */ public boolean useTrailingSlashMatch() { return this.trailingSlashMatch; } /** - * Whether to apply suffix pattern matching in PatternsRequestCondition. + * Set whether to apply suffix pattern matching in PatternsRequestCondition. *

By default this is set to 'true'. * @see #setRegisteredSuffixPatternMatch(boolean) */ @@ -581,14 +599,17 @@ public final class RequestMappingInfo implements RequestConditionBy default this is not set. */ - public void setContentNegotiationManager(ContentNegotiationManager manager) { - this.contentNegotiationManager = manager; + public void setContentNegotiationManager(ContentNegotiationManager contentNegotiationManager) { + this.contentNegotiationManager = contentNegotiationManager; } + /** + * Return the ContentNegotiationManager to use for the ProducesRequestCondition, + * if any. + */ public ContentNegotiationManager getContentNegotiationManager() { return this.contentNegotiationManager; } diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java index 5ffb6aaf5c8..9365f0474bb 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java @@ -115,7 +115,7 @@ public class RequestMappingHandlerMapping extends RequestMappingInfoHandlerMappi @Override public void afterPropertiesSet() { this.config = new RequestMappingInfo.BuilderConfiguration(); - this.config.setPathHelper(getUrlPathHelper()); + this.config.setUrlPathHelper(getUrlPathHelper()); this.config.setPathMatcher(getPathMatcher()); this.config.setSuffixPatternMatch(this.useSuffixPatternMatch); this.config.setTrailingSlashMatch(this.useTrailingSlashMatch); diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java index 471ae154613..901d0c5eac6 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java @@ -27,6 +27,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.web.filter.OncePerRequestFilter; +import org.springframework.web.util.UrlPathHelper; /** * A filter that wraps the {@link HttpServletResponse} and overrides its @@ -96,13 +97,14 @@ public class ResourceUrlEncodingFilter extends OncePerRequestFilter { private void initLookupPath(ResourceUrlProvider urlProvider) { if (this.indexLookupPath == null) { - String requestUri = urlProvider.getPathHelper().getRequestUri(this.request); - String lookupPath = urlProvider.getPathHelper().getLookupPathForRequest(this.request); + UrlPathHelper pathHelper = urlProvider.getUrlPathHelper(); + String requestUri = pathHelper.getRequestUri(this.request); + String lookupPath = pathHelper.getLookupPathForRequest(this.request); this.indexLookupPath = requestUri.lastIndexOf(lookupPath); this.prefixLookupPath = requestUri.substring(0, this.indexLookupPath); if ("/".equals(lookupPath) && !"/".equals(requestUri)) { - String contextPath = urlProvider.getPathHelper().getContextPath(this.request); + String contextPath = pathHelper.getContextPath(this.request); if (requestUri.equals(contextPath)) { this.indexLookupPath = requestUri.length(); this.prefixLookupPath = requestUri; diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java index 9ee0c5a8b70..f39e02ff22b 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java @@ -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"); * you may not use this file except in compliance with the License. @@ -51,7 +51,7 @@ public class ResourceUrlProvider implements ApplicationListener