Skip to content

Commit a680880

Browse files
committed
Restore attributes for failed AND/OR request predicates
This commit restores the attributes when either of the predicates in an AND/OR conjunction is false. Issue: SPR-17210
1 parent 8e83f14 commit a680880

File tree

2 files changed

+58
-12
lines changed

2 files changed

+58
-12
lines changed

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

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Arrays;
2424
import java.util.Collections;
2525
import java.util.EnumSet;
26+
import java.util.HashMap;
2627
import java.util.HashSet;
2728
import java.util.LinkedHashMap;
2829
import java.util.List;
@@ -349,6 +350,11 @@ private static void traceMatch(String prefix, Object desired, @Nullable Object a
349350
}
350351
}
351352

353+
private static void restoreAttributes(ServerRequest request, Map<String, Object> attributes) {
354+
request.attributes().clear();
355+
request.attributes().putAll(attributes);
356+
}
357+
352358

353359
private static class HttpMethodPredicate implements RequestPredicate {
354360

@@ -518,8 +524,14 @@ public AndRequestPredicate(RequestPredicate left, RequestPredicate right) {
518524
}
519525

520526
@Override
521-
public boolean test(ServerRequest t) {
522-
return (this.left.test(t) && this.right.test(t));
527+
public boolean test(ServerRequest request) {
528+
Map<String, Object> oldAttributes = new HashMap<>(request.attributes());
529+
530+
if (this.left.test(request) && this.right.test(request)) {
531+
return true;
532+
}
533+
restoreAttributes(request, oldAttributes);
534+
return false;
523535
}
524536

525537
@Override
@@ -533,7 +545,6 @@ public String toString() {
533545
}
534546
}
535547

536-
537548
/**
538549
* {@link RequestPredicate} for where either {@code left} or {@code right} predicates
539550
* may match.
@@ -552,8 +563,20 @@ public OrRequestPredicate(RequestPredicate left, RequestPredicate right) {
552563
}
553564

554565
@Override
555-
public boolean test(ServerRequest t) {
556-
return (this.left.test(t) || this.right.test(t));
566+
public boolean test(ServerRequest request) {
567+
Map<String, Object> oldAttributes = new HashMap<>(request.attributes());
568+
569+
if (this.left.test(request)) {
570+
return true;
571+
}
572+
else {
573+
restoreAttributes(request, oldAttributes);
574+
if (this.right.test(request)) {
575+
return true;
576+
}
577+
}
578+
restoreAttributes(request, oldAttributes);
579+
return false;
557580
}
558581

559582
@Override

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

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,23 @@
1616

1717
package org.springframework.web.reactive.function.server;
1818

19+
import java.util.Map;
20+
1921
import org.junit.Test;
2022
import reactor.core.publisher.Mono;
2123

24+
import org.springframework.http.HttpMethod;
2225
import org.springframework.http.HttpStatus;
2326
import org.springframework.http.ResponseEntity;
2427
import org.springframework.web.client.RestTemplate;
2528

2629
import static org.junit.Assert.*;
27-
import static org.springframework.web.reactive.function.server.RequestPredicates.*;
28-
import static org.springframework.web.reactive.function.server.RouterFunctions.*;
30+
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
31+
import static org.springframework.web.reactive.function.server.RequestPredicates.all;
32+
import static org.springframework.web.reactive.function.server.RequestPredicates.method;
33+
import static org.springframework.web.reactive.function.server.RequestPredicates.path;
34+
import static org.springframework.web.reactive.function.server.RouterFunctions.nest;
35+
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
2936

3037
/**
3138
* @author Arjen Poutsma
@@ -45,7 +52,8 @@ protected RouterFunction<?> routerFunction() {
4552
route(GET("/bar"), nestedHandler::variables).and(
4653
nest(GET("/{bar}"),
4754
route(GET("/{baz}"), nestedHandler::variables))))
48-
.andRoute(GET("/{qux}/quux"), nestedHandler::variables);
55+
.andRoute(path("/{qux}/quux").and(method(HttpMethod.GET)), nestedHandler::variables)
56+
.andRoute(all(), nestedHandler::variables);
4957
}
5058

5159

@@ -89,7 +97,7 @@ public void parentVariables() {
8997

9098
// SPR 16692
9199
@Test
92-
public void removeFailedPathVariables() {
100+
public void removeFailedNestedPathVariables() {
93101
ResponseEntity<String> result =
94102
restTemplate.getForEntity("http://localhost:" + port + "/qux/quux", String.class);
95103

@@ -98,6 +106,17 @@ public void removeFailedPathVariables() {
98106

99107
}
100108

109+
// SPR 17210
110+
@Test
111+
public void removeFailedPathVariablesAnd() {
112+
ResponseEntity<String> result =
113+
restTemplate.postForEntity("http://localhost:" + port + "/qux/quux", "", String.class);
114+
115+
assertEquals(HttpStatus.OK, result.getStatusCode());
116+
assertEquals("{}", result.getBody());
117+
118+
}
119+
101120

102121
private static class NestedHandler {
103122

@@ -109,11 +128,15 @@ public Mono<ServerResponse> baz(ServerRequest request) {
109128
return ServerResponse.ok().syncBody("baz");
110129
}
111130

131+
@SuppressWarnings("unchecked")
112132
public Mono<ServerResponse> variables(ServerRequest request) {
113-
assertEquals(request.pathVariables(),
114-
request.attributes().get(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE));
133+
Map<String, String> pathVariables = request.pathVariables();
134+
Map<String, String> attributePathVariables =
135+
(Map<String, String>) request.attributes().get(RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE);
136+
assertTrue( (pathVariables.equals(attributePathVariables))
137+
|| (pathVariables.isEmpty() && (attributePathVariables == null)));
115138

116-
Mono<String> responseBody = Mono.just(request.pathVariables().toString());
139+
Mono<String> responseBody = Mono.just(pathVariables.toString());
117140
return ServerResponse.ok().body(responseBody, String.class);
118141
}
119142

0 commit comments

Comments
 (0)