diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicate.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicate.java index 52a5724f1a..0f23918f74 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicate.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicate.java @@ -55,7 +55,7 @@ public interface RequestPredicate { * @return a predicate that represents the logical negation of this predicate */ default RequestPredicate negate() { - return t -> !test(t); + return new RequestPredicates.NegateRequestPredicate(this); } /** diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java index cc9a625958..eda84732e8 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java @@ -575,7 +575,34 @@ public abstract class RequestPredicates { } /** - * {@link RequestPredicate} for where either {@code left} or {@code right} predicates + * {@link RequestPredicate} that negates a delegate predicate. + */ + static class NegateRequestPredicate implements RequestPredicate { + private final RequestPredicate delegate; + + public NegateRequestPredicate(RequestPredicate delegate) { + Assert.notNull(delegate, "Delegate must not be null"); + this.delegate = delegate; + } + + @Override + public boolean test(ServerRequest request) { + Map oldAttributes = new HashMap<>(request.attributes()); + boolean result = !this.delegate.test(request); + if (!result) { + restoreAttributes(request, oldAttributes); + } + return result; + } + + @Override + public String toString() { + return "!" + this.delegate.toString(); + } + } + + /** + * {@link RequestPredicate} where either {@code left} or {@code right} predicates * may match. */ static class OrRequestPredicate implements RequestPredicate {