前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Cloud Alibaba - 25 Gateway-路由断言工厂Route Predicate Factories谓词工厂示例及源码解析

Spring Cloud Alibaba - 25 Gateway-路由断言工厂Route Predicate Factories谓词工厂示例及源码解析

作者头像
小小工匠
发布2022-02-14 08:47:00
2900
发布2022-02-14 08:47:00
举报
文章被收录于专栏:小工匠聊架构小工匠聊架构

文章目录

在这里插入图片描述
在这里插入图片描述

官网

https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gateway-request-predicates-factories

在这里插入图片描述
在这里插入图片描述

Spring Cloud Gateway 将路由匹配为 Spring WebFluxHandlerMapping基础架构的一部分。Spring Cloud Gateway 包含许多内置的路由谓词工厂。所有这些谓词都匹配 HTTP 请求的不同属性。我们可以将多个路由谓词工厂与逻辑and语句结合起来。


The After Route Predicate Factory

https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-after-route-predicate-factory

在这里插入图片描述
在这里插入图片描述

小栗子

我们还是继续老工程 ,启动

artisan-cloud-gateway 【8888】

artisan-cloud-gateway-order

artisan-cloud-gateway-product


【网关配置】

application-after_route.yml

代码语言:javascript
复制
#  网关的After谓词,对应的源码处理AfterRoutePredicateFactory
#作用: 经过网关的所有请求 当前时间>比After阈值  就进行转发
#现在我们是2022年了 currentTime
spring:
  cloud:
    gateway: #gateway
      routes:
        - id: after_route  # id 确保唯一
          uri: lb://artisan-cloud-gateway-order  #  nacos上的 注册地址
          predicates:
            - After=2025-02-13T18:27:28.309+08:00[Asia/Shanghai]

currentTime

激活配置文件

在这里插入图片描述
在这里插入图片描述

【测试】

在这里插入图片描述
在这里插入图片描述

符合预期。

如果我们改下时间呢?

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

AfterRoutePredicateFactory源码

代码语言:javascript
复制
public class AfterRoutePredicateFactory
		extends AbstractRoutePredicateFactory<AfterRoutePredicateFactory.Config> {

	/**
	 * DateTime key.
	 */
	public static final String DATETIME_KEY = "datetime";

	public AfterRoutePredicateFactory() {
		super(Config.class);
	}

	@Override
	public List<String> shortcutFieldOrder() {
		return Collections.singletonList(DATETIME_KEY);
	}

	@Override
	public Predicate<ServerWebExchange> apply(Config config) {
		return new GatewayPredicate() {
			@Override
			public boolean test(ServerWebExchange serverWebExchange) {
				final ZonedDateTime now = ZonedDateTime.now();
				return now.isAfter(config.getDatetime());
			}

			@Override
			public String toString() {
				return String.format("After: %s", config.getDatetime());
			}
		};
	}

	public static class Config {

		@NotNull
		private ZonedDateTime datetime;

		public ZonedDateTime getDatetime() {
			return datetime;
		}

		public void setDatetime(ZonedDateTime datetime) {
			this.datetime = datetime;
		}

	}

}

核心方法,apply,比较简单。


The Before Route Predicate Factory

https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-before-route-predicate-factory

在这里插入图片描述
在这里插入图片描述

小栗子

application-before_route.yml

代码语言:javascript
复制
#目的:测试网关的Before谓词,对应的源码处理BeforeRoutePredicateFactory
#作用: 经过网关的所有请求当前时间 比Before=2021-02-13T18:27:28.309+08:00[Asia/Shanghai] 小  就进行转发
#现在2022年了 时间比配置的阈值大,所以我们不会进行转发,而返回404
#2021-02-13T18:27:28.309+08:00[Asia/Shanghai] 这个时间怎么获取的呢? --- System.out.println(ZonedDateTime.now())
spring:
  cloud:
    gateway: #gateway
      routes:
        - id: before_route  # id 确保唯一
          uri: lb://artisan-cloud-gateway-order
          predicates:
            - Before=2023-02-13T18:27:28.309+08:00[Asia/Shanghai]

BeforeRoutePredicateFactory源码

代码语言:javascript
复制
public class BeforeRoutePredicateFactory
		extends AbstractRoutePredicateFactory<BeforeRoutePredicateFactory.Config> {

	/**
	 * DateTime key.
	 */
	public static final String DATETIME_KEY = "datetime";

	public BeforeRoutePredicateFactory() {
		super(Config.class);
	}

	@Override
	public List<String> shortcutFieldOrder() {
		return Collections.singletonList(DATETIME_KEY);
	}

	@Override
	public Predicate<ServerWebExchange> apply(Config config) {
		return new GatewayPredicate() {
			@Override
			public boolean test(ServerWebExchange serverWebExchange) {
				final ZonedDateTime now = ZonedDateTime.now();
				return now.isBefore(config.getDatetime());
			}

			@Override
			public String toString() {
				return String.format("Before: %s", config.getDatetime());
			}
		};
	}

	public static class Config {

		private ZonedDateTime datetime;

		public ZonedDateTime getDatetime() {
			return datetime;
		}

		public void setDatetime(ZonedDateTime datetime) {
			this.datetime = datetime;
		}

	}

}

The Between Route Predicate Factory

https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-between-route-predicate-factory

在这里插入图片描述
在这里插入图片描述

小栗子

application-between-route.yml

代码语言:javascript
复制
# Between谓词  BetweenRoutePredicateFactory
# 就是经过网关请求的当前时间 currentTime 满足
# Between startTime < currentTime < Between EndTime 才进行转发
spring:
  cloud:
    gateway:
      routes:
        - id: between-route #id必须要唯一
          uri: lb://artisan-cloud-gateway-order  # 这里可以使用负载均衡的写法
          predicates:
            - Between=2020-02-13T18:27:28.309+08:00[Asia/Shanghai],2025-02-13T18:27:28.309+08:00[Asia/Shanghai]

BetweenRoutePredicateFactory源码

代码语言:javascript
复制
public class BetweenRoutePredicateFactory
		extends AbstractRoutePredicateFactory<BetweenRoutePredicateFactory.Config> {

	/**
	 * DateTime 1 key.
	 */
	public static final String DATETIME1_KEY = "datetime1";

	/**
	 * DateTime 2 key.
	 */
	public static final String DATETIME2_KEY = "datetime2";

	public BetweenRoutePredicateFactory() {
		super(Config.class);
	}

	@Override
	public List<String> shortcutFieldOrder() {
		return Arrays.asList(DATETIME1_KEY, DATETIME2_KEY);
	}

	@Override
	public Predicate<ServerWebExchange> apply(Config config) {
		Assert.isTrue(config.getDatetime1().isBefore(config.getDatetime2()),
				config.getDatetime1() + " must be before " + config.getDatetime2());

		return new GatewayPredicate() {
			@Override
			public boolean test(ServerWebExchange serverWebExchange) {
				final ZonedDateTime now = ZonedDateTime.now();
				return now.isAfter(config.getDatetime1())
						&& now.isBefore(config.getDatetime2());
			}

			@Override
			public String toString() {
				return String.format("Between: %s and %s", config.getDatetime1(),
						config.getDatetime2());
			}
		};
	}

	@Validated
	public static class Config {

		@NotNull
		private ZonedDateTime datetime1;

		@NotNull
		private ZonedDateTime datetime2;

		public ZonedDateTime getDatetime1() {
			return datetime1;
		}

		public Config setDatetime1(ZonedDateTime datetime1) {
			this.datetime1 = datetime1;
			return this;
		}

		public ZonedDateTime getDatetime2() {
			return datetime2;
		}

		public Config setDatetime2(ZonedDateTime datetime2) {
			this.datetime2 = datetime2;
			return this;
		}

	}

}

The Cookie Route Predicate Factory

https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-cookie-route-predicate-factory

在这里插入图片描述
在这里插入图片描述

小栗子

application-cookie-route.yml

代码语言:javascript
复制
#谓词 Cookie 源码  CookieRoutePredicateFactory
#表示通过网关的请求 必须带入包含了Cookie name=Company value=Artisan
#才转发请求
spring:
  cloud:
    gateway:
      routes:
        - id: cookie-route #id必须要唯一
          uri: lb://artisan-cloud-gateway-order  # 这里可以使用负载均衡的写法
          predicates:
            #当我们的请求中包含了Cookie name=Company value=Artisan
            #才转发请求
            - Cookie=Company,Artisan

CookieRoutePredicateFactory源码

核心方法

代码语言:javascript
复制
@Override
	public Predicate<ServerWebExchange> apply(Config config) {
		return new GatewayPredicate() {
			@Override
			public boolean test(ServerWebExchange exchange) {
				List<HttpCookie> cookies = exchange.getRequest().getCookies()
						.get(config.name);
				if (cookies == null) {
					return false;
				}
				for (HttpCookie cookie : cookies) {
					if (cookie.getValue().matches(config.regexp)) {
						return true;
					}
				}
				return false;
			}

			@Override
			public String toString() {
				return String.format("Cookie: name=%s regexp=%s", config.name,
						config.regexp);
			}
		};
	}

The Header Route Predicate Factory

https://cloud.spring.io/spring-cloud-gateway/reference/html/#the-header-route-predicate-factory

在这里插入图片描述
在这里插入图片描述

小栗子

application-header-route.yml

代码语言:javascript
复制
#Header谓词   源码HeaderRoutePredicateFactory
#说明请求经过网关 必须带入
#header的k=X-Request-appId v=Artisan才会被转发
spring:
  cloud:
    gateway:
      routes:
        - id: header-route #id必须要唯一
          uri: lb://artisan-cloud-gateway-order
          predicates:
            - Header=X-Request-appId,Artisan

HeaderRoutePredicateFactory源码

代码语言:javascript
复制
@Override
	public Predicate<ServerWebExchange> apply(Config config) {
		boolean hasRegex = !StringUtils.isEmpty(config.regexp);

		return new GatewayPredicate() {
			@Override
			public boolean test(ServerWebExchange exchange) {
				List<String> values = exchange.getRequest().getHeaders()
						.getOrDefault(config.header, Collections.emptyList());
				if (values.isEmpty()) {
					return false;
				}
				// values is now guaranteed to not be empty
				if (hasRegex) {
					// check if a header value matches
					return values.stream()
							.anyMatch(value -> value.matches(config.regexp));
				}

				// there is a value and since regexp is empty, we only check existence.
				return true;
			}

			@Override
			public String toString() {
				return String.format("Header: %s regexp=%s", config.header,
						config.regexp);
			}
		};
	}

The Host Route Predicate Factory

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
#Host谓词  源码HostRoutePredicateFactory 
#说明请求http://localhost:8888/selectOrderInfoById/1的
#Host必须满足www.artisan.com:8888或者localhost:8888才会
#转发到http://artisan-cloud-gateway-order/selectOrderInfoById/1

#而127.0.0.1不会被转发
spring:
  cloud:
    gateway:
      routes:
        - id: host-route #id必须要唯一
          uri: lb://artisan-cloud-gateway-order
          predicates:
            - Host=www.artisan.com:8888,localhost:8888

The Method Route Predicate Factory

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
#Http请求方法的谓词 Method 源码 MethodRoutePredicateFactory 
#表示经过网关的请求 只有post方式才能被转发
spring:
  cloud:
    gateway:
      routes:
       - id: method #id必须要唯一
         uri: lb://artisan-cloud-gateway-order
         predicates:
           #当前请求的方式 http://localhost:8888/selectOrderInfoById/1 是Post才会被转发
           #到http://artisan-cloud-gateway-order/selectOrderInfoById/1
           - Method=Post

The Path Route Predicate Factory

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

The Query Route Predicate Factory

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

The RemoteAddr Route Predicate Factory

在这里插入图片描述
在这里插入图片描述

The Weight Route Predicate Factory

在这里插入图片描述
在这里插入图片描述

源码

https://github.com/yangshangwei/SpringCloudAlibabMaster

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-02-13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 官网
  • The After Route Predicate Factory
    • 小栗子
      • AfterRoutePredicateFactory源码
      • The Before Route Predicate Factory
        • 小栗子
          • BeforeRoutePredicateFactory源码
          • The Between Route Predicate Factory
            • 小栗子
              • BetweenRoutePredicateFactory源码
              • The Cookie Route Predicate Factory
                • 小栗子
                  • CookieRoutePredicateFactory源码
                  • The Header Route Predicate Factory
                    • 小栗子
                      • HeaderRoutePredicateFactory源码
                      • The Host Route Predicate Factory
                      • The Method Route Predicate Factory
                      • The Path Route Predicate Factory
                      • The Query Route Predicate Factory
                      • The RemoteAddr Route Predicate Factory
                      • The Weight Route Predicate Factory
                      • 源码
                      相关产品与服务
                      负载均衡
                      负载均衡(Cloud Load Balancer,CLB)提供安全快捷的流量分发服务,访问流量经由 CLB 可以自动分配到云中的多台后端服务器上,扩展系统的服务能力并消除单点故障。负载均衡支持亿级连接和千万级并发,可轻松应对大流量访问,满足业务需求。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档