Skip to content

Commit 1cd994d

Browse files
committed
Encapsulate full path initialization
1 parent 3d28c02 commit 1cd994d

File tree

10 files changed

+52
-56
lines changed

10 files changed

+52
-56
lines changed

spring-web/src/main/java/org/springframework/web/util/pattern/PathPatternParser.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2020 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -17,6 +17,7 @@
1717
package org.springframework.web.util.pattern;
1818

1919
import org.springframework.http.server.PathContainer;
20+
import org.springframework.util.StringUtils;
2021

2122
/**
2223
* Parser for URI path patterns producing {@link PathPattern} instances that can
@@ -96,6 +97,17 @@ public PathContainer.Options getPathOptions() {
9697
}
9798

9899

100+
/**
101+
* Prepare the given pattern for use in matching to full URL paths.
102+
* <p>By default, prepend a leading slash if needed for non-empty patterns.
103+
* @param pattern the pattern to initialize
104+
* @return the updated pattern
105+
* @since 5.2.25
106+
*/
107+
public String initFullPathPattern(String pattern) {
108+
return (StringUtils.hasLength(pattern) && !pattern.startsWith("/") ? "/" + pattern : pattern);
109+
}
110+
99111
/**
100112
* Process the path pattern content, a character at a time, breaking it into
101113
* path elements around separator boundaries and verifying the structure at each

spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -109,10 +109,9 @@ public static RequestPredicate methods(HttpMethod... httpMethods) {
109109
*/
110110
public static RequestPredicate path(String pattern) {
111111
Assert.notNull(pattern, "'pattern' must not be null");
112-
if (!pattern.isEmpty() && !pattern.startsWith("/")) {
113-
pattern = "/" + pattern;
114-
}
115-
return pathPredicates(PathPatternParser.defaultInstance).apply(pattern);
112+
PathPatternParser parser = PathPatternParser.defaultInstance;
113+
pattern = parser.initFullPathPattern(pattern);
114+
return pathPredicates(parser).apply(pattern);
116115
}
117116

118117
/**

spring-webflux/src/main/java/org/springframework/web/reactive/handler/AbstractUrlHandlerMapping.java

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@
2929
import org.springframework.http.server.PathContainer;
3030
import org.springframework.lang.Nullable;
3131
import org.springframework.util.Assert;
32-
import org.springframework.util.StringUtils;
3332
import org.springframework.web.server.ServerWebExchange;
3433
import org.springframework.web.util.pattern.PathPattern;
34+
import org.springframework.web.util.pattern.PathPatternParser;
3535

3636
/**
3737
* Abstract base class for URL-mapped
@@ -211,8 +211,9 @@ protected void registerHandler(String urlPath, Object handler) throws BeansExcep
211211
Object resolvedHandler = handler;
212212

213213
// Parse path pattern
214-
urlPath = prependLeadingSlash(urlPath);
215-
PathPattern pattern = getPathPatternParser().parse(urlPath);
214+
PathPatternParser parser = getPathPatternParser();
215+
urlPath = parser.initFullPathPattern(urlPath);
216+
PathPattern pattern = parser.parse(urlPath);
216217
if (this.handlerMap.containsKey(pattern)) {
217218
Object existingHandler = this.handlerMap.get(pattern);
218219
if (existingHandler != null && existingHandler != resolvedHandler) {
@@ -241,14 +242,4 @@ private String getHandlerDescription(Object handler) {
241242
return (handler instanceof String ? "'" + handler + "'" : handler.toString());
242243
}
243244

244-
245-
private static String prependLeadingSlash(String pattern) {
246-
if (StringUtils.hasLength(pattern) && !pattern.startsWith("/")) {
247-
return "/" + pattern;
248-
}
249-
else {
250-
return pattern;
251-
}
252-
}
253-
254245
}

spring-webflux/src/main/java/org/springframework/web/reactive/resource/ResourceUrlProvider.java

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -35,7 +35,6 @@
3535
import org.springframework.http.server.PathContainer;
3636
import org.springframework.http.server.reactive.ServerHttpRequest;
3737
import org.springframework.lang.Nullable;
38-
import org.springframework.util.StringUtils;
3938
import org.springframework.web.reactive.handler.SimpleUrlHandlerMapping;
4039
import org.springframework.web.server.ServerWebExchange;
4140
import org.springframework.web.util.pattern.PathPattern;
@@ -86,8 +85,9 @@ public Map<PathPattern, ResourceWebHandler> getHandlerMap() {
8685
public void registerHandlers(Map<String, ResourceWebHandler> handlerMap) {
8786
this.handlerMap.clear();
8887
handlerMap.forEach((rawPattern, resourceWebHandler) -> {
89-
rawPattern = prependLeadingSlash(rawPattern);
90-
PathPattern pattern = PathPatternParser.defaultInstance.parse(rawPattern);
88+
PathPatternParser parser = PathPatternParser.defaultInstance;
89+
rawPattern = parser.initFullPathPattern(rawPattern);
90+
PathPattern pattern = parser.parse(rawPattern);
9191
this.handlerMap.put(pattern, resourceWebHandler);
9292
});
9393
}
@@ -173,14 +173,4 @@ private Mono<String> resolveResourceUrl(ServerWebExchange exchange, PathContaine
173173
});
174174
}
175175

176-
177-
private static String prependLeadingSlash(String pattern) {
178-
if (StringUtils.hasLength(pattern) && !pattern.startsWith("/")) {
179-
return "/" + pattern;
180-
}
181-
else {
182-
return pattern;
183-
}
184-
}
185-
186176
}

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/RequestMappingInfo.java

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -602,11 +602,9 @@ static List<PathPattern> parse(String[] patterns, PathPatternParser parser) {
602602
return Collections.emptyList();
603603
}
604604
List<PathPattern> result = new ArrayList<>(patterns.length);
605-
for (String path : patterns) {
606-
if (StringUtils.hasText(path) && !path.startsWith("/")) {
607-
path = "/" + path;
608-
}
609-
result.add(parser.parse(path));
605+
for (String pattern : patterns) {
606+
pattern = parser.initFullPathPattern(pattern);
607+
result.add(parser.parse(pattern));
610608
}
611609
return result;
612610
}

spring-webmvc/src/main/java/org/springframework/web/servlet/function/RequestPredicates.java

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2021 the original author or authors.
2+
* Copyright 2002-2023 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.
@@ -108,10 +108,9 @@ public static RequestPredicate methods(HttpMethod... httpMethods) {
108108
*/
109109
public static RequestPredicate path(String pattern) {
110110
Assert.notNull(pattern, "'pattern' must not be null");
111-
if (!pattern.isEmpty() && !pattern.startsWith("/")) {
112-
pattern = "/" + pattern;
113-
}
114-
return pathPredicates(PathPatternParser.defaultInstance).apply(pattern);
111+
PathPatternParser parser = PathPatternParser.defaultInstance;
112+
pattern = parser.initFullPathPattern(pattern);
113+
return pathPredicates(parser).apply(pattern);
115114
}
116115

117116
/**

spring-webmvc/src/main/java/org/springframework/web/servlet/handler/HandlerMappingIntrospector.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
import org.springframework.web.servlet.HandlerMapping;
5252
import org.springframework.web.util.ServletRequestPathUtils;
5353
import org.springframework.web.util.UrlPathHelper;
54+
import org.springframework.web.util.pattern.PathPatternParser;
5455

5556
/**
5657
* Helper class to get information from the {@code HandlerMapping} that would
@@ -327,10 +328,15 @@ private static class LookupPathMatchableHandlerMapping implements MatchableHandl
327328
ServletRequestPathUtils.PATH_ATTRIBUTE : UrlPathHelper.PATH_ATTRIBUTE);
328329
}
329330

331+
@Override
332+
public PathPatternParser getPatternParser() {
333+
return this.delegate.getPatternParser();
334+
}
335+
330336
@Nullable
331337
@Override
332338
public RequestMatchResult match(HttpServletRequest request, String pattern) {
333-
pattern = (StringUtils.hasLength(pattern) && !pattern.startsWith("/") ? "/" + pattern : pattern);
339+
pattern = initFullPathPattern(pattern);
334340
Object previousPath = request.getAttribute(this.pathAttributeName);
335341
request.setAttribute(this.pathAttributeName, this.lookupPath);
336342
try {
@@ -341,6 +347,11 @@ public RequestMatchResult match(HttpServletRequest request, String pattern) {
341347
}
342348
}
343349

350+
private String initFullPathPattern(String pattern) {
351+
PathPatternParser parser = (getPatternParser() != null ? getPatternParser() : PathPatternParser.defaultInstance);
352+
return parser.initFullPathPattern(pattern);
353+
}
354+
344355
@Nullable
345356
@Override
346357
public HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PathPatternsRequestCondition.java

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,9 @@ private static SortedSet<PathPattern> parse(PathPatternParser parser, String...
7575
return EMPTY_PATH_PATTERN;
7676
}
7777
SortedSet<PathPattern> result = new TreeSet<>();
78-
for (String path : patterns) {
79-
if (StringUtils.hasText(path) && !path.startsWith("/")) {
80-
path = "/" + path;
81-
}
82-
result.add(parser.parse(path));
78+
for (String pattern : patterns) {
79+
pattern = parser.initFullPathPattern(pattern);
80+
result.add(parser.parse(pattern));
8381
}
8482
return result;
8583
}

spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/condition/PatternsRequestCondition.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.springframework.util.StringUtils;
3636
import org.springframework.web.util.UrlPathHelper;
3737
import org.springframework.web.util.pattern.PathPattern;
38+
import org.springframework.web.util.pattern.PathPatternParser;
3839

3940
/**
4041
* A logical disjunction (' || ') request condition that matches a request
@@ -156,9 +157,7 @@ private static Set<String> initPatterns(String[] patterns) {
156157
}
157158
Set<String> result = new LinkedHashSet<>(patterns.length);
158159
for (String pattern : patterns) {
159-
if (StringUtils.hasLength(pattern) && !pattern.startsWith("/")) {
160-
pattern = "/" + pattern;
161-
}
160+
pattern = PathPatternParser.defaultInstance.initFullPathPattern(pattern);
162161
result.add(pattern);
163162
}
164163
return result;

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
import org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping;
6666
import org.springframework.web.servlet.support.ServletUriComponentsBuilder;
6767
import org.springframework.web.util.UriComponentsBuilder;
68+
import org.springframework.web.util.pattern.PathPatternParser;
6869

6970
/**
7071
* Creates instances of {@link org.springframework.web.util.UriComponentsBuilder}
@@ -544,9 +545,7 @@ private static UriComponentsBuilder fromMethodInternal(@Nullable UriComponentsBu
544545
String typePath = getClassMapping(controllerType);
545546
String methodPath = getMethodMapping(method);
546547
String path = pathMatcher.combine(typePath, methodPath);
547-
if (StringUtils.hasLength(path) && !path.startsWith("/")) {
548-
path = "/" + path;
549-
}
548+
path = PathPatternParser.defaultInstance.initFullPathPattern(path);
550549
builder.path(path);
551550

552551
return applyContributors(builder, method, args);

0 commit comments

Comments
 (0)