文章目录
- 官网
- 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
- 源码
官网
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