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;
|
package org.springframework.web.reactive.function.server;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
@ -460,12 +462,28 @@ public abstract class RouterFunctions {
|
||||||
"Nested predicate \"%s\" matches against \"%s\"",
|
"Nested predicate \"%s\" matches against \"%s\"",
|
||||||
this.predicate, serverRequest));
|
this.predicate, serverRequest));
|
||||||
}
|
}
|
||||||
return this.routerFunction.route(nestedRequest);
|
return this.routerFunction.route(nestedRequest)
|
||||||
|
.doOnNext(match -> {
|
||||||
|
mergeTemplateVariables(serverRequest, nestedRequest.pathVariables());
|
||||||
|
});
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.orElseGet(Mono::empty);
|
.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
|
@Override
|
||||||
public void accept(Visitor visitor) {
|
public void accept(Visitor visitor) {
|
||||||
visitor.startNested(this.predicate);
|
visitor.startNested(this.predicate);
|
||||||
|
|
|
||||||
|
|
@ -44,8 +44,9 @@ public class NestedRouteIntegrationTests extends AbstractRouterFunctionIntegrati
|
||||||
route(GET("/bar"), nestedHandler::bar)
|
route(GET("/bar"), nestedHandler::bar)
|
||||||
.andRoute(GET("/baz"), nestedHandler::baz))
|
.andRoute(GET("/baz"), nestedHandler::baz))
|
||||||
.andNest(GET("/{foo}"),
|
.andNest(GET("/{foo}"),
|
||||||
|
route(GET("/bar"), nestedHandler::variables).and(
|
||||||
nest(GET("/{bar}"),
|
nest(GET("/{bar}"),
|
||||||
route(GET("/{baz}"), nestedHandler::variables)))
|
route(GET("/{baz}"), nestedHandler::variables))))
|
||||||
.andRoute(GET("/{qux}/quux"), 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());
|
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
|
// SPR 16692
|
||||||
@Test
|
@Test
|
||||||
public void removeFailedPathVariables() throws Exception {
|
public void removeFailedPathVariables() throws Exception {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue