Skip to content

Commit 51325af

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
1 parent 03af55a commit 51325af

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
@@ -362,10 +362,7 @@ public boolean test(ServerRequest request) {
362362
@Override
363363
public Optional<ServerRequest> nest(ServerRequest request) {
364364
return Optional.ofNullable(this.pattern.matchStartOfPath(request.pathContainer()))
365-
.map(info -> {
366-
mergeTemplateVariables(request, info.getUriVariables());
367-
return new SubPathServerRequestWrapper(request, info);
368-
});
365+
.map(info -> new SubPathServerRequestWrapper(request, info));
369366
}
370367

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

476473
private final PathContainer subPathContainer;
477474

475+
private final Map<String, String> pathVariables;
478476

479477
public SubPathServerRequestWrapper(ServerRequest request, PathPattern.PathRemainingMatchInfo info) {
480478
this.request = request;
481479
this.subPathContainer = new SubPathContainer(info.getPathRemaining());
480+
481+
this.pathVariables = mergePathVariables(request, info.getUriVariables());
482+
}
483+
484+
private static Map<String, String> mergePathVariables(ServerRequest request,
485+
Map<String, String> pathVariables) {
486+
487+
Map<String, String> result = new LinkedHashMap<>(request.pathVariables());
488+
result.putAll(pathVariables);
489+
return Collections.unmodifiableMap(result);
482490
}
483491

484492
@Override
@@ -581,14 +589,9 @@ public MultiValueMap<String, String> queryParams() {
581589
return this.request.queryParams();
582590
}
583591

584-
@Override
585-
public String pathVariable(String name) {
586-
return this.request.pathVariable(name);
587-
}
588-
589592
@Override
590593
public Map<String, String> pathVariables() {
591-
return this.request.pathVariables();
594+
return this.pathVariables;
592595
}
593596

594597
@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)