Skip to content

Commit 82ca201

Browse files
committed
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)
1 parent 482dd2c commit 82ca201

File tree

5 files changed

+80
-35
lines changed

5 files changed

+80
-35
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
@@ -51,42 +51,46 @@
5151
* @author Rossen Stoyanchev
5252
* @since 3.2
5353
*/
54-
public class PathExtensionContentNegotiationStrategy
55-
extends AbstractMappingContentNegotiationStrategy {
56-
57-
private static final Log logger = LogFactory.getLog(PathExtensionContentNegotiationStrategy.class);
54+
public class PathExtensionContentNegotiationStrategy extends AbstractMappingContentNegotiationStrategy {
5855

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

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

61+
private UrlPathHelper urlPathHelper = new UrlPathHelper();
6862

6963
private boolean useJaf = true;
7064

7165
private boolean ignoreUnknownExtensions = true;
7266

7367

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

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

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

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

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -537,13 +537,25 @@ public static class BuilderConfiguration {
537537
private ContentNegotiationManager contentNegotiationManager;
538538

539539
/**
540-
* Set a custom UrlPathHelper to use for the PatternsRequestCondition.
541-
* <p>By default this is not set.
540+
* @deprecated as of Spring 4.2.8, in favor of {@link #setUrlPathHelper}
542541
*/
542+
@Deprecated
543543
public void setPathHelper(UrlPathHelper pathHelper) {
544544
this.urlPathHelper = pathHelper;
545545
}
546546

547+
/**
548+
* Set a custom UrlPathHelper to use for the PatternsRequestCondition.
549+
* <p>By default this is not set.
550+
* @since 4.2.8
551+
*/
552+
public void setUrlPathHelper(UrlPathHelper urlPathHelper) {
553+
this.urlPathHelper = urlPathHelper;
554+
}
555+
556+
/**
557+
* Return a custom UrlPathHelper to use for the PatternsRequestCondition, if any.
558+
*/
547559
public UrlPathHelper getUrlPathHelper() {
548560
return this.urlPathHelper;
549561
}
@@ -556,39 +568,48 @@ public void setPathMatcher(PathMatcher pathMatcher) {
556568
this.pathMatcher = pathMatcher;
557569
}
558570

571+
/**
572+
* Return a custom PathMatcher to use for the PatternsRequestCondition, if any.
573+
*/
559574
public PathMatcher getPathMatcher() {
560575
return this.pathMatcher;
561576
}
562577

563578
/**
564-
* Whether to apply trailing slash matching in PatternsRequestCondition.
579+
* Set whether to apply trailing slash matching in PatternsRequestCondition.
565580
* <p>By default this is set to 'true'.
566581
*/
567582
public void setTrailingSlashMatch(boolean trailingSlashMatch) {
568583
this.trailingSlashMatch = trailingSlashMatch;
569584
}
570585

586+
/**
587+
* Return whether to apply trailing slash matching in PatternsRequestCondition.
588+
*/
571589
public boolean useTrailingSlashMatch() {
572590
return this.trailingSlashMatch;
573591
}
574592

575593
/**
576-
* Whether to apply suffix pattern matching in PatternsRequestCondition.
594+
* Set whether to apply suffix pattern matching in PatternsRequestCondition.
577595
* <p>By default this is set to 'true'.
578596
* @see #setRegisteredSuffixPatternMatch(boolean)
579597
*/
580598
public void setSuffixPatternMatch(boolean suffixPatternMatch) {
581599
this.suffixPatternMatch = suffixPatternMatch;
582600
}
583601

602+
/**
603+
* Return whether to apply suffix pattern matching in PatternsRequestCondition.
604+
*/
584605
public boolean useSuffixPatternMatch() {
585606
return this.suffixPatternMatch;
586607
}
587608

588609
/**
589-
* Whether suffix pattern matching should be restricted to registered
610+
* Set whether suffix pattern matching should be restricted to registered
590611
* file extensions only. Setting this property also sets
591-
* suffixPatternMatch=true and requires that a
612+
* {@code suffixPatternMatch=true} and requires that a
592613
* {@link #setContentNegotiationManager} is also configured in order to
593614
* obtain the registered file extensions.
594615
*/
@@ -597,6 +618,10 @@ public void setRegisteredSuffixPatternMatch(boolean registeredSuffixPatternMatch
597618
this.suffixPatternMatch = (registeredSuffixPatternMatch || this.suffixPatternMatch);
598619
}
599620

621+
/**
622+
* Return whether suffix pattern matching should be restricted to registered
623+
* file extensions only.
624+
*/
600625
public boolean useRegisteredSuffixPatternMatch() {
601626
return this.registeredSuffixPatternMatch;
602627
}
@@ -617,10 +642,14 @@ public List<String> getFileExtensions() {
617642
* Set the ContentNegotiationManager to use for the ProducesRequestCondition.
618643
* <p>By default this is not set.
619644
*/
620-
public void setContentNegotiationManager(ContentNegotiationManager manager) {
621-
this.contentNegotiationManager = manager;
645+
public void setContentNegotiationManager(ContentNegotiationManager contentNegotiationManager) {
646+
this.contentNegotiationManager = contentNegotiationManager;
622647
}
623648

649+
/**
650+
* Return the ContentNegotiationManager to use for the ProducesRequestCondition,
651+
* if any.
652+
*/
624653
public ContentNegotiationManager getContentNegotiationManager() {
625654
return this.contentNegotiationManager;
626655
}

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
@@ -115,7 +115,7 @@ public void setEmbeddedValueResolver(StringValueResolver resolver) {
115115
@Override
116116
public void afterPropertiesSet() {
117117
this.config = new RequestMappingInfo.BuilderConfiguration();
118-
this.config.setPathHelper(getUrlPathHelper());
118+
this.config.setUrlPathHelper(getUrlPathHelper());
119119
this.config.setPathMatcher(getPathMatcher());
120120
this.config.setSuffixPatternMatch(this.useSuffixPatternMatch);
121121
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: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2015 the original author or authors.
2+
* Copyright 2002-2016 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -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,24 @@ 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
*/
76+
public UrlPathHelper getUrlPathHelper() {
77+
return this.urlPathHelper;
78+
}
79+
80+
/**
81+
* @deprecated as of Spring 4.2.8, in favor of {@link #getUrlPathHelper}
82+
*/
83+
@Deprecated
7584
public UrlPathHelper getPathHelper() {
76-
return this.pathHelper;
85+
return this.urlPathHelper;
7786
}
7887

7988
/**
@@ -135,6 +144,7 @@ public void onApplicationEvent(ContextRefreshedEvent event) {
135144
}
136145
}
137146

147+
138148
protected void detectResourceHandlers(ApplicationContext appContext) {
139149
logger.debug("Looking for resource handler mappings");
140150

@@ -158,7 +168,6 @@ protected void detectResourceHandlers(ApplicationContext appContext) {
158168
}
159169
}
160170

161-
162171
/**
163172
* A variation on {@link #getForLookupPath(String)} that accepts a full request
164173
* URL path (i.e. including context and servlet path) and returns the full request
@@ -181,8 +190,9 @@ public final String getForRequestUrl(HttpServletRequest request, String requestU
181190
}
182191

183192
private int getLookupPathIndex(HttpServletRequest request) {
184-
String requestUri = getPathHelper().getRequestUri(request);
185-
String lookupPath = getPathHelper().getLookupPathForRequest(request);
193+
UrlPathHelper pathHelper = getUrlPathHelper();
194+
String requestUri = pathHelper.getRequestUri(request);
195+
String lookupPath = pathHelper.getLookupPathForRequest(request);
186196
return requestUri.indexOf(lookupPath);
187197
}
188198

0 commit comments

Comments
 (0)