Skip to content

Commit 84afc60

Browse files
committed
Configurable UrlPathHelper in PathExtensionContentNegotiationStrategy
This commit also aligns ResourceUrlProvider's and RequestMappingInfo's UrlPathHelper setter/getter signatures. Issue: SPR-14454
1 parent e91c1cd commit 84afc60

File tree

5 files changed

+63
-34
lines changed

5 files changed

+63
-34
lines changed

spring-web/src/main/java/org/springframework/web/accept/PathExtensionContentNegotiationStrategy.java

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -52,42 +52,46 @@
5252
* @author Rossen Stoyanchev
5353
* @since 3.2
5454
*/
55-
public class PathExtensionContentNegotiationStrategy
56-
extends AbstractMappingContentNegotiationStrategy {
57-
58-
private static final Log logger = LogFactory.getLog(PathExtensionContentNegotiationStrategy.class);
55+
public class PathExtensionContentNegotiationStrategy extends AbstractMappingContentNegotiationStrategy {
5956

6057
private static final boolean JAF_PRESENT = ClassUtils.isPresent("javax.activation.FileTypeMap",
6158
PathExtensionContentNegotiationStrategy.class.getClassLoader());
6259

63-
private static final UrlPathHelper PATH_HELPER = new UrlPathHelper();
64-
65-
static {
66-
PATH_HELPER.setUrlDecode(false);
67-
}
60+
private static final Log logger = LogFactory.getLog(PathExtensionContentNegotiationStrategy.class);
6861

62+
private UrlPathHelper urlPathHelper = new UrlPathHelper();
6963

7064
private boolean useJaf = true;
7165

7266
private boolean ignoreUnknownExtensions = true;
7367

7468

69+
/**
70+
* Create an instance without any mappings to start with. Mappings may be added
71+
* later on if any extensions are resolved through the Java Activation framework.
72+
*/
73+
public PathExtensionContentNegotiationStrategy() {
74+
this(null);
75+
}
76+
7577
/**
7678
* Create an instance with the given map of file extensions and media types.
7779
*/
7880
public PathExtensionContentNegotiationStrategy(Map<String, MediaType> mediaTypes) {
7981
super(mediaTypes);
82+
this.urlPathHelper.setUrlDecode(false);
8083
}
8184

85+
8286
/**
83-
* Create an instance without any mappings to start with. Mappings may be added
84-
* later on if any extensions are resolved through the Java Activation framework.
87+
* Configure a {@code UrlPathHelper} to use in {@link #getMediaTypeKey}
88+
* in order to derive the lookup path for a target request URL path.
89+
* @since 4.2.8
8590
*/
86-
public PathExtensionContentNegotiationStrategy() {
87-
super(null);
91+
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
92+
this.urlPathHelper = urlPathHelper;
8893
}
8994

90-
9195
/**
9296
* Whether to use the Java Activation Framework to look up file extensions.
9397
* <p>By default this is set to "true" but depends on JAF being present.
@@ -113,7 +117,7 @@ protected String getMediaTypeKey(NativeWebRequest webRequest) {
113117
logger.warn("An HttpServletRequest is required to determine the media type key");
114118
return null;
115119
}
116-
String path = PATH_HELPER.getLookupPathForRequest(request);
120+
String path = this.urlPathHelper.getLookupPathForRequest(request);
117121
String filename = WebUtils.extractFullFilenameFromUrlPath(path);
118122
String extension = StringUtils.getFilenameExtension(filename);
119123
return (StringUtils.hasText(extension)) ? extension.toLowerCase(Locale.ENGLISH) : null;

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/RequestMappingInfo.java

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -523,11 +523,15 @@ public static class BuilderConfiguration {
523523
/**
524524
* Set a custom UrlPathHelper to use for the PatternsRequestCondition.
525525
* <p>By default this is not set.
526+
* @since 4.2.8
526527
*/
527-
public void setPathHelper(UrlPathHelper pathHelper) {
528+
public void setUrlPathHelper(UrlPathHelper pathHelper) {
528529
this.urlPathHelper = pathHelper;
529530
}
530531

532+
/**
533+
* Return a custom UrlPathHelper to use for the PatternsRequestCondition, if any.
534+
*/
531535
public UrlPathHelper getUrlPathHelper() {
532536
return this.urlPathHelper;
533537
}
@@ -540,39 +544,48 @@ public void setPathMatcher(PathMatcher pathMatcher) {
540544
this.pathMatcher = pathMatcher;
541545
}
542546

547+
/**
548+
* Return a custom PathMatcher to use for the PatternsRequestCondition, if any.
549+
*/
543550
public PathMatcher getPathMatcher() {
544551
return this.pathMatcher;
545552
}
546553

547554
/**
548-
* Whether to apply trailing slash matching in PatternsRequestCondition.
555+
* Set whether to apply trailing slash matching in PatternsRequestCondition.
549556
* <p>By default this is set to 'true'.
550557
*/
551558
public void setTrailingSlashMatch(boolean trailingSlashMatch) {
552559
this.trailingSlashMatch = trailingSlashMatch;
553560
}
554561

562+
/**
563+
* Return whether to apply trailing slash matching in PatternsRequestCondition.
564+
*/
555565
public boolean useTrailingSlashMatch() {
556566
return this.trailingSlashMatch;
557567
}
558568

559569
/**
560-
* Whether to apply suffix pattern matching in PatternsRequestCondition.
570+
* Set whether to apply suffix pattern matching in PatternsRequestCondition.
561571
* <p>By default this is set to 'true'.
562572
* @see #setRegisteredSuffixPatternMatch(boolean)
563573
*/
564574
public void setSuffixPatternMatch(boolean suffixPatternMatch) {
565575
this.suffixPatternMatch = suffixPatternMatch;
566576
}
567577

578+
/**
579+
* Return whether to apply suffix pattern matching in PatternsRequestCondition.
580+
*/
568581
public boolean useSuffixPatternMatch() {
569582
return this.suffixPatternMatch;
570583
}
571584

572585
/**
573-
* Whether suffix pattern matching should be restricted to registered
586+
* Set whether suffix pattern matching should be restricted to registered
574587
* file extensions only. Setting this property also sets
575-
* suffixPatternMatch=true and requires that a
588+
* {@code suffixPatternMatch=true} and requires that a
576589
* {@link #setContentNegotiationManager} is also configured in order to
577590
* obtain the registered file extensions.
578591
*/
@@ -581,6 +594,10 @@ public void setRegisteredSuffixPatternMatch(boolean registeredSuffixPatternMatch
581594
this.suffixPatternMatch = (registeredSuffixPatternMatch || this.suffixPatternMatch);
582595
}
583596

597+
/**
598+
* Return whether suffix pattern matching should be restricted to registered
599+
* file extensions only.
600+
*/
584601
public boolean useRegisteredSuffixPatternMatch() {
585602
return this.registeredSuffixPatternMatch;
586603
}
@@ -601,10 +618,14 @@ public List<String> getFileExtensions() {
601618
* Set the ContentNegotiationManager to use for the ProducesRequestCondition.
602619
* <p>By default this is not set.
603620
*/
604-
public void setContentNegotiationManager(ContentNegotiationManager manager) {
605-
this.contentNegotiationManager = manager;
621+
public void setContentNegotiationManager(ContentNegotiationManager contentNegotiationManager) {
622+
this.contentNegotiationManager = contentNegotiationManager;
606623
}
607624

625+
/**
626+
* Return the ContentNegotiationManager to use for the ProducesRequestCondition,
627+
* if any.
628+
*/
608629
public ContentNegotiationManager getContentNegotiationManager() {
609630
return this.contentNegotiationManager;
610631
}

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/RequestMappingHandlerMapping.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ public void setEmbeddedValueResolver(StringValueResolver resolver) {
118118
@Override
119119
public void afterPropertiesSet() {
120120
this.config = new RequestMappingInfo.BuilderConfiguration();
121-
this.config.setPathHelper(getUrlPathHelper());
121+
this.config.setUrlPathHelper(getUrlPathHelper());
122122
this.config.setPathMatcher(getPathMatcher());
123123
this.config.setSuffixPatternMatch(this.useSuffixPatternMatch);
124124
this.config.setTrailingSlashMatch(this.useTrailingSlashMatch);

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlEncodingFilter.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.apache.commons.logging.LogFactory;
2828

2929
import org.springframework.web.filter.OncePerRequestFilter;
30+
import org.springframework.web.util.UrlPathHelper;
3031

3132
/**
3233
* A filter that wraps the {@link HttpServletResponse} and overrides its
@@ -96,13 +97,14 @@ private ResourceUrlProvider getResourceUrlProvider() {
9697

9798
private void initLookupPath(ResourceUrlProvider urlProvider) {
9899
if (this.indexLookupPath == null) {
99-
String requestUri = urlProvider.getPathHelper().getRequestUri(this.request);
100-
String lookupPath = urlProvider.getPathHelper().getLookupPathForRequest(this.request);
100+
UrlPathHelper pathHelper = urlProvider.getUrlPathHelper();
101+
String requestUri = pathHelper.getRequestUri(this.request);
102+
String lookupPath = pathHelper.getLookupPathForRequest(this.request);
101103
this.indexLookupPath = requestUri.lastIndexOf(lookupPath);
102104
this.prefixLookupPath = requestUri.substring(0, this.indexLookupPath);
103105

104106
if ("/".equals(lookupPath) && !"/".equals(requestUri)) {
105-
String contextPath = urlProvider.getPathHelper().getContextPath(this.request);
107+
String contextPath = pathHelper.getContextPath(this.request);
106108
if (requestUri.equals(contextPath)) {
107109
this.indexLookupPath = requestUri.length();
108110
this.prefixLookupPath = requestUri;

spring-webmvc/src/main/java/org/springframework/web/servlet/resource/ResourceUrlProvider.java

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
5151

5252
protected final Log logger = LogFactory.getLog(getClass());
5353

54-
private UrlPathHelper pathHelper = new UrlPathHelper();
54+
private UrlPathHelper urlPathHelper = new UrlPathHelper();
5555

5656
private PathMatcher pathMatcher = new AntPathMatcher();
5757

@@ -65,15 +65,16 @@ public class ResourceUrlProvider implements ApplicationListener<ContextRefreshed
6565
* {@link #getForRequestUrl(javax.servlet.http.HttpServletRequest, String)}
6666
* in order to derive the lookup path for a target request URL path.
6767
*/
68-
public void setUrlPathHelper(UrlPathHelper pathHelper) {
69-
this.pathHelper = pathHelper;
68+
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
69+
this.urlPathHelper = urlPathHelper;
7070
}
7171

7272
/**
7373
* Return the configured {@code UrlPathHelper}.
74+
* @since 4.2.8
7475
*/
75-
public UrlPathHelper getPathHelper() {
76-
return this.pathHelper;
76+
public UrlPathHelper getUrlPathHelper() {
77+
return this.urlPathHelper;
7778
}
7879

7980
/**
@@ -135,6 +136,7 @@ public void onApplicationEvent(ContextRefreshedEvent event) {
135136
}
136137
}
137138

139+
138140
protected void detectResourceHandlers(ApplicationContext appContext) {
139141
logger.debug("Looking for resource handler mappings");
140142

@@ -158,7 +160,6 @@ protected void detectResourceHandlers(ApplicationContext appContext) {
158160
}
159161
}
160162

161-
162163
/**
163164
* A variation on {@link #getForLookupPath(String)} that accepts a full request
164165
* URL path (i.e. including context and servlet path) and returns the full request
@@ -181,8 +182,9 @@ public final String getForRequestUrl(HttpServletRequest request, String requestU
181182
}
182183

183184
private int getLookupPathIndex(HttpServletRequest request) {
184-
String requestUri = getPathHelper().getRequestUri(request);
185-
String lookupPath = getPathHelper().getLookupPathForRequest(request);
185+
UrlPathHelper pathHelper = getUrlPathHelper();
186+
String requestUri = pathHelper.getRequestUri(request);
187+
String lookupPath = pathHelper.getLookupPathForRequest(request);
186188
return requestUri.indexOf(lookupPath);
187189
}
188190

0 commit comments

Comments
 (0)