Browse Source

Fix parent path variables in nested route functions

This commit fix an issue where path variables in a nested parent
RouterFunction were not committed to the request attributes.

Issue: SPR-16868
pull/1842/head
Arjen Poutsma 7 years ago
parent
commit
8c30b8e628
  1. 20
      spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RouterFunctions.java
  2. 22
      spring-webflux/src/test/java/org/springframework/web/reactive/function/server/NestedRouteIntegrationTests.java

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

@ -16,6 +16,8 @@ @@ -16,6 +16,8 @@
package org.springframework.web.reactive.function.server;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@ -460,12 +462,28 @@ public abstract class RouterFunctions { @@ -460,12 +462,28 @@ public abstract class RouterFunctions {
"Nested predicate \"%s\" matches against \"%s\"",
this.predicate, serverRequest));
}
return this.routerFunction.route(nestedRequest);
return this.routerFunction.route(nestedRequest)
.doOnNext(match -> {
mergeTemplateVariables(serverRequest, nestedRequest.pathVariables());
});
}
)
.orElseGet(Mono::empty);
}
@SuppressWarnings("unchecked")
private void mergeTemplateVariables(ServerRequest request, Map<String, String> variables) {
if (!variables.isEmpty()) {
Map<String, Object> attributes = request.attributes();
Map<String, String> oldVariables = (Map<String, String>)request.attribute(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE)
.orElseGet(LinkedHashMap::new);
Map<String, String> mergedVariables = new LinkedHashMap<>(oldVariables);
mergedVariables.putAll(variables);
attributes.put(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE,
Collections.unmodifiableMap(mergedVariables));
}
}
@Override
public void accept(Visitor visitor) {
visitor.startNested(this.predicate);

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

@ -41,11 +41,12 @@ public class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrati @@ -41,11 +41,12 @@ public class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrati
protected RouterFunction<?> routerFunction() {
NestedHandler nestedHandler = new NestedHandler();
return nest(path("/foo/"),
route(GET("/bar"), nestedHandler::bar)
.andRoute(GET("/baz"), nestedHandler::baz))
.andNest(GET("/{foo}"),
nest(GET("/{bar}"),
route(GET("/{baz}"), nestedHandler::variables)))
route(GET("/bar"), nestedHandler::bar)
.andRoute(GET("/baz"), nestedHandler::baz))
.andNest(GET("/{foo}"),
route(GET("/bar"), nestedHandler::variables).and(
nest(GET("/{bar}"),
route(GET("/{baz}"), nestedHandler::variables))))
.andRoute(GET("/{qux}/quux"), nestedHandler::variables);
}
@ -77,6 +78,17 @@ public class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrati @@ -77,6 +78,17 @@ public class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrati
assertEquals("{foo=1, bar=2, baz=3}", result.getBody());
}
// SPR-16868
@Test
public void parentVariables() throws Exception {
ResponseEntity<String> result =
restTemplate.getForEntity("http://localhost:" + port + "/1/bar", String.class);
assertEquals(HttpStatus.OK, result.getStatusCode());
assertEquals("{foo=1}", result.getBody());
}
// SPR 16692
@Test
public void removeFailedPathVariables() throws Exception {

Loading…
Cancel
Save