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
This commit is contained in:
parent
e57d8e1e60
commit
8c30b8e628
|
|
@ -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 {
|
|||
"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);
|
||||
|
|
|
|||
|
|
@ -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
|
|||
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…
Reference in New Issue