From 5f04e0f16da93d8233189ef369b92d63048dbd1c Mon Sep 17 00:00:00 2001 From: bunny <1319900154@qq.com> Date: Tue, 27 May 2025 14:30:37 +0800 Subject: [PATCH] =?UTF-8?q?:sparkles:=20gateway-=E6=96=AD=E8=A8=80-?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=96=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../predicates/VipRoutePredicateFactory.java | 50 ++++++++++++++++++ .../src/main/resources/application-route.yaml | 18 +++++++ cloud-demo/images/image-20250527140215610.png | Bin 0 -> 18744 bytes 3 files changed, 68 insertions(+) create mode 100644 cloud-demo/gateway/src/main/java/cn/bunny/gateway/predicates/VipRoutePredicateFactory.java create mode 100644 cloud-demo/images/image-20250527140215610.png diff --git a/cloud-demo/gateway/src/main/java/cn/bunny/gateway/predicates/VipRoutePredicateFactory.java b/cloud-demo/gateway/src/main/java/cn/bunny/gateway/predicates/VipRoutePredicateFactory.java new file mode 100644 index 0000000..17c18b1 --- /dev/null +++ b/cloud-demo/gateway/src/main/java/cn/bunny/gateway/predicates/VipRoutePredicateFactory.java @@ -0,0 +1,50 @@ +package cn.bunny.gateway.predicates; + +import jakarta.validation.constraints.NotEmpty; +import lombok.Getter; +import lombok.Setter; +import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory; +import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate; +import org.springframework.http.server.reactive.ServerHttpRequest; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; +import org.springframework.validation.annotation.Validated; +import org.springframework.web.server.ServerWebExchange; + +import java.util.List; +import java.util.function.Predicate; + +@Component +public class VipRoutePredicateFactory extends AbstractRoutePredicateFactory { + + public VipRoutePredicateFactory() { + super(Config.class); + } + + @Override + public List shortcutFieldOrder() { + return List.of("param", "value"); + } + + @Override + public Predicate apply(Config config) { + return (GatewayPredicate) serverWebExchange -> { + ServerHttpRequest request = serverWebExchange.getRequest(); + + String first = request.getQueryParams().getFirst(config.param); + + return StringUtils.hasText(first) && first.equals(config.value); + }; + } + + @Getter + @Setter + @Validated + public static class Config { + @NotEmpty + private String param; + + @NotEmpty + private String value; + } +} diff --git a/cloud-demo/gateway/src/main/resources/application-route.yaml b/cloud-demo/gateway/src/main/resources/application-route.yaml index c44b01e..42e676b 100644 --- a/cloud-demo/gateway/src/main/resources/application-route.yaml +++ b/cloud-demo/gateway/src/main/resources/application-route.yaml @@ -13,5 +13,23 @@ spring: args: patterns: /api/product/** matchTrailingSlash: true + - id: bing-route + uri: https://cn.bing.com/ + predicates: + - name: Path + args: + patterns: /search + - name: Query + args: + param: q + regexp: 被世界温柔以待 + # 短写法 + # - Vip=User,bunny + + # 长写法 + - name: Vip + args: + param: user + value: bunny diff --git a/cloud-demo/images/image-20250527140215610.png b/cloud-demo/images/image-20250527140215610.png new file mode 100644 index 0000000000000000000000000000000000000000..3b9aea4fd19ce293ce1ba1574e14b0ac9c33973a GIT binary patch literal 18744 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