Skip to content

Commit a63f04d

Browse files
committed
Clean up path variables after non match
This commit makes sure the nested path variables are only commited to the attributes when all predicates match. Issue: SPR-16692 (cherry picked from commit 51325af)
1 parent 5a98516 commit a63f04d

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

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

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -359,10 +359,7 @@ public boolean test(ServerRequest request) {
359359
@Override
360360
public Optional<ServerRequest> nest(ServerRequest request) {
361361
return Optional.ofNullable(this.pattern.matchStartOfPath(request.pathContainer()))
362-
.map(info -> {
363-
mergeTemplateVariables(request, info.getUriVariables());
364-
return new SubPathServerRequestWrapper(request, info);
365-
});
362+
.map(info -> new SubPathServerRequestWrapper(request, info));
366363
}
367364

368365
private void mergeTemplateVariables(ServerRequest request, Map<String, String> variables) {
@@ -472,10 +469,21 @@ private static class SubPathServerRequestWrapper implements ServerRequest {
472469

473470
private final PathContainer subPathContainer;
474471

472+
private final Map<String, String> pathVariables;
475473

476474
public SubPathServerRequestWrapper(ServerRequest request, PathPattern.PathRemainingMatchInfo info) {
477475
this.request = request;
478476
this.subPathContainer = new SubPathContainer(info.getPathRemaining());
477+
478+
this.pathVariables = mergePathVariables(request, info.getUriVariables());
479+
}
480+
481+
private static Map<String, String> mergePathVariables(ServerRequest request,
482+
Map<String, String> pathVariables) {
483+
484+
Map<String, String> result = new LinkedHashMap<>(request.pathVariables());
485+
result.putAll(pathVariables);
486+
return Collections.unmodifiableMap(result);
479487
}
480488

481489
@Override
@@ -568,14 +576,9 @@ public MultiValueMap<String, String> queryParams() {
568576
return this.request.queryParams();
569577
}
570578

571-
@Override
572-
public String pathVariable(String name) {
573-
return this.request.pathVariable(name);
574-
}
575-
576579
@Override
577580
public Map<String, String> pathVariables() {
578-
return this.request.pathVariables();
581+
return this.pathVariables;
579582
}
580583

581584
@Override

spring-webflux/src/test/java/org/springframework/web/reactive/function/server/NestedRouteIntegrationTests.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 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,7 +17,6 @@
1717
package org.springframework.web.reactive.function.server;
1818

1919
import org.junit.Test;
20-
import reactor.core.publisher.Flux;
2120
import reactor.core.publisher.Mono;
2221

2322
import org.springframework.http.HttpStatus;
@@ -46,7 +45,8 @@ protected RouterFunction<?> routerFunction() {
4645
.andRoute(GET("/baz"), nestedHandler::baz))
4746
.andNest(GET("/{foo}"),
4847
nest(GET("/{bar}"),
49-
route(GET("/{baz}"), nestedHandler::variables)));
48+
route(GET("/{baz}"), nestedHandler::variables)))
49+
.andRoute(GET("/{qux}/quux"), nestedHandler::variables);
5050
}
5151

5252

@@ -74,7 +74,18 @@ public void variables() throws Exception {
7474
restTemplate.getForEntity("http://localhost:" + port + "/1/2/3", String.class);
7575

7676
assertEquals(HttpStatus.OK, result.getStatusCode());
77-
assertEquals("1-2-3", result.getBody());
77+
assertEquals("{foo=1, bar=2, baz=3}", result.getBody());
78+
}
79+
80+
// SPR 16692
81+
@Test
82+
public void removeFailedPathVariables() throws Exception {
83+
ResponseEntity<String> result =
84+
restTemplate.getForEntity("http://localhost:" + port + "/qux/quux", String.class);
85+
86+
assertEquals(HttpStatus.OK, result.getStatusCode());
87+
assertEquals("{qux=qux}", result.getBody());
88+
7889
}
7990

8091

@@ -89,11 +100,13 @@ public Mono<ServerResponse> baz(ServerRequest request) {
89100
}
90101

91102
public Mono<ServerResponse> variables(ServerRequest request) {
92-
Flux<String> responseBody =
93-
Flux.just(request.pathVariable("foo"), "-", request.pathVariable("bar"), "-",
94-
request.pathVariable("baz"));
103+
assertEquals(request.pathVariables(),
104+
request.attributes().get(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE));
105+
106+
Mono<String> responseBody = Mono.just(request.pathVariables().toString());
95107
return ServerResponse.ok().body(responseBody, String.class);
96108
}
109+
97110
}
98111

99112
}

0 commit comments

Comments
 (0)