Merge pull request #1856 from dkapil/gh-1789
GH-1789 Added matchTrailingSlash parameter to use instead of matchOpt…
This commit is contained in:
@@ -270,7 +270,7 @@ This route matches if the request method was a `GET` or a `POST`.
|
||||
|
||||
=== The Path Route Predicate Factory
|
||||
|
||||
The `Path` Route Predicate Factory takes two parameters: a list of Spring `PathMatcher` `patterns` and an optional flag called `matchOptionalTrailingSeparator`.
|
||||
The `Path` Route Predicate Factory takes two parameters: a list of Spring `PathMatcher` `patterns` and an optional flag called `matchTrailingSlash` (defaults to `true`).
|
||||
The following example configures a path route predicate:
|
||||
|
||||
.application.yml
|
||||
@@ -288,7 +288,9 @@ spring:
|
||||
----
|
||||
====
|
||||
|
||||
This route matches if the request path was, for example: `/red/1` or `/red/blue` or `/blue/green`.
|
||||
This route matches if the request path was, for example: `/red/1` or `/red/1/` or `/red/blue` or `/blue/green`.
|
||||
|
||||
If `matchTrailingSlash` is set to `false`, then request path `/red/1/` will not be matched.
|
||||
|
||||
This predicate extracts the URI template variables (such as `segment`, defined in the preceding example) as a map of names and values and places it in the `ServerWebExchange.getAttributes()` with a key defined in `ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE`.
|
||||
Those values are then available for use by <<gateway-route-filters,`GatewayFilter` factories>>
|
||||
|
||||
@@ -38,13 +38,14 @@ import static org.springframework.http.server.PathContainer.parsePath;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Dhawal Kapil
|
||||
*/
|
||||
public class PathRoutePredicateFactory
|
||||
extends AbstractRoutePredicateFactory<PathRoutePredicateFactory.Config> {
|
||||
|
||||
private static final Log log = LogFactory.getLog(RoutePredicateFactory.class);
|
||||
private static final Log log = LogFactory.getLog(PathRoutePredicateFactory.class);
|
||||
|
||||
private static final String MATCH_OPTIONAL_TRAILING_SEPARATOR_KEY = "matchOptionalTrailingSeparator";
|
||||
private static final String MATCH_TRAILING_SLASH = "matchTrailingSlash";
|
||||
|
||||
private PathPatternParser pathPatternParser = new PathPatternParser();
|
||||
|
||||
@@ -67,7 +68,7 @@ public class PathRoutePredicateFactory
|
||||
|
||||
@Override
|
||||
public List<String> shortcutFieldOrder() {
|
||||
return Arrays.asList("patterns", MATCH_OPTIONAL_TRAILING_SEPARATOR_KEY);
|
||||
return Arrays.asList("patterns", MATCH_TRAILING_SLASH);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,8 +80,8 @@ public class PathRoutePredicateFactory
|
||||
public Predicate<ServerWebExchange> apply(Config config) {
|
||||
final ArrayList<PathPattern> pathPatterns = new ArrayList<>();
|
||||
synchronized (this.pathPatternParser) {
|
||||
pathPatternParser.setMatchOptionalTrailingSeparator(
|
||||
config.isMatchOptionalTrailingSeparator());
|
||||
pathPatternParser
|
||||
.setMatchOptionalTrailingSeparator(config.isMatchTrailingSlash());
|
||||
config.getPatterns().forEach(pattern -> {
|
||||
PathPattern pathPattern = this.pathPatternParser.parse(pattern);
|
||||
pathPatterns.add(pathPattern);
|
||||
@@ -111,7 +112,7 @@ public class PathRoutePredicateFactory
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("Paths: %s, match trailing slash: %b",
|
||||
config.getPatterns(), config.isMatchOptionalTrailingSeparator());
|
||||
config.getPatterns(), config.isMatchTrailingSlash());
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -121,7 +122,7 @@ public class PathRoutePredicateFactory
|
||||
|
||||
private List<String> patterns = new ArrayList<>();
|
||||
|
||||
private boolean matchOptionalTrailingSeparator = true;
|
||||
private boolean matchTrailingSlash = true;
|
||||
|
||||
public List<String> getPatterns() {
|
||||
return patterns;
|
||||
@@ -132,22 +133,37 @@ public class PathRoutePredicateFactory
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #isMatchTrailingSlash()}
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isMatchOptionalTrailingSeparator() {
|
||||
return matchOptionalTrailingSeparator;
|
||||
return isMatchTrailingSlash();
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #setMatchTrailingSlash(boolean)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Config setMatchOptionalTrailingSeparator(
|
||||
boolean matchOptionalTrailingSeparator) {
|
||||
this.matchOptionalTrailingSeparator = matchOptionalTrailingSeparator;
|
||||
setMatchTrailingSlash(matchOptionalTrailingSeparator);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean isMatchTrailingSlash() {
|
||||
return matchTrailingSlash;
|
||||
}
|
||||
|
||||
public Config setMatchTrailingSlash(boolean matchTrailingSlash) {
|
||||
this.matchTrailingSlash = matchTrailingSlash;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return new ToStringCreator(this).append("patterns", patterns)
|
||||
.append("matchOptionalTrailingSeparator",
|
||||
matchOptionalTrailingSeparator)
|
||||
.toString();
|
||||
.append(MATCH_TRAILING_SLASH, matchTrailingSlash).toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -185,14 +185,14 @@ public class PredicateSpec extends UriSpec {
|
||||
* A predicate that checks if the path of the request matches the given pattern
|
||||
* @param patterns the pattern to check the path against. The pattern is a
|
||||
* {@link org.springframework.util.PathMatcher} pattern
|
||||
* @param matchOptionalTrailingSeparator set to false if you do not want this path to
|
||||
* @param matchTrailingSlash set to false if you do not want this path to
|
||||
* match when there is a trailing <code>/</code>
|
||||
* @return a {@link BooleanSpec} to be used to add logical operators
|
||||
*/
|
||||
public BooleanSpec path(boolean matchOptionalTrailingSeparator, String... patterns) {
|
||||
public BooleanSpec path(boolean matchTrailingSlash, String... patterns) {
|
||||
return asyncPredicate(getBean(PathRoutePredicateFactory.class).applyAsync(c -> c
|
||||
.setPatterns(Arrays.asList(patterns))
|
||||
.setMatchOptionalTrailingSeparator(matchOptionalTrailingSeparator)));
|
||||
.setMatchTrailingSlash(matchTrailingSlash)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.springframework.context.annotation.Import;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.test.annotation.DirtiesContext;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
import org.springframework.web.server.ServerWebExchange;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
|
||||
@@ -98,6 +99,13 @@ public class PathRoutePredicateFactoryTests extends BaseWebClientTests {
|
||||
.expectHeader().valueEquals(ROUTE_ID_HEADER, "path_test");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void matchOptionalTrailingSeparatorCopiedToMatchTrailingSlash() {
|
||||
Config config = new Config().setPatterns(Arrays.asList("patternA", "patternB"))
|
||||
.setMatchOptionalTrailingSeparator(false);
|
||||
assertThat(config.isMatchTrailingSlash()).isEqualTo(false);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringFormat() {
|
||||
Config config = new Config().setPatterns(Arrays.asList("patternA", "patternB"))
|
||||
@@ -107,6 +115,16 @@ public class PathRoutePredicateFactoryTests extends BaseWebClientTests {
|
||||
.contains("false");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void toStringFormatMatchTrailingSlashTrue() {
|
||||
Config config = new Config().setPatterns(Arrays.asList("patternA", "patternB"))
|
||||
.setMatchTrailingSlash(true);
|
||||
Predicate<ServerWebExchange> predicate = new PathRoutePredicateFactory().apply(config);
|
||||
assertThat(predicate.toString()).contains("patternA").contains("patternB")
|
||||
.contains("true");
|
||||
}
|
||||
|
||||
|
||||
@EnableAutoConfiguration
|
||||
@SpringBootConfiguration
|
||||
@Import(DefaultTestConfig.class)
|
||||
|
||||
Reference in New Issue
Block a user