Gateway Request Predicates
Spring Cloud Gateway MVC 作为 Spring WebMvc.fn HandlerMapping
基础架构的一部分匹配路由。Spring Cloud Gateway 重用了 WebMvc.fn 中的许多 RequestPredicate
实现,并包含其他自定义 RequestPredicate
实现。所有这些谓词都匹配 HTTP 请求的不同属性。您可以使用 RequestPredicate.and()
和 RequestPredicate.or()
方法组合多个路由谓词工厂。
The After Request Predicate
After
路由谓词工厂接受一个参数,即一个 datetime
(它是 java ZonedDateTime
)。此谓词匹配在指定 datetime 之后发生的请求。以下示例配置一个 after 路由谓词:
spring:
cloud:
gateway:
mvc:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
import java.time.ZonedDateTime;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.after;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsAfter() {
return route("after_route")
.route(after(ZonedDateTime.parse("2017-01-20T17:42:47.789-07:00[America/Denver]")), http("https://example.org"))
.build();
}
}
此路由匹配 2017 年 1 月 20 日 17:42 山地时间(丹佛)之后发送的任何请求。
The Before Request Predicate
Before
路由谓词工厂接受一个参数,即一个 datetime
(它是 java ZonedDateTime
)。此谓词匹配在指定 datetime
之前发生的请求。以下示例配置一个 before 路由谓词:
spring:
cloud:
gateway:
mvc:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
import java.time.ZonedDateTime;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.before;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsBefore() {
return route("before_route")
.route(before(ZonedDateTime.parse("2017-01-20T17:42:47.789-07:00[America/Denver]")), http("https://example.org"))
.build();
}
}
此路由匹配 2017 年 1 月 20 日 17:42 山地时间(丹佛)之前发送的任何请求。
The Between Request Predicate
Between
路由谓词工厂接受两个参数,它们是 datetime1
和 datetime2
,它们是 java ZonedDateTime
对象。此谓词匹配在 datetime1
之后和在 datetime2
之前发生的请求。datetime2
参数必须在 datetime1
之后。以下示例配置一个 between 路由谓词:
spring:
cloud:
gateway:
mvc:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
import java.time.ZonedDateTime;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.between;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsBetween() {
return route("between_route")
.route(between(ZonedDateTime.parse("2017-01-20T17:42:47.789-07:00[America/Denver]"), ZonedDateTime.parse("2017-01-21T17:42:47.789-07:00[America/Denver]")), http("https://example.org"))
.build();
}
}
此路由匹配 2017 年 1 月 20 日 17:42 山地时间(丹佛)之后和在 2017 年 1 月 21 日 17:42 山地时间(丹佛)之前发生的任何请求。这对于维护窗口可能很有用。
The Cookie Request Predicate
Cookie
路由谓词工厂接受两个参数,即 Cookie name
和一个 regexp
(它是 java 正则表达式)。此谓词匹配具有给定名称且其值与正则表达式匹配的 Cookie。以下示例配置一个 cookie 路由谓词工厂:
spring:
cloud:
gateway:
mvc:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.between;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsCookie() {
return route("cookie_route")
.route(cookie("chocolate", "ch.p"), http("https://example.org"))
.build();
}
}
此路由匹配具有名为 chocolate
的 Cookie 且其值与 ch.p
正则表达式匹配的请求。
The Header Request Predicate
Header
路由谓词工厂接受两个参数,即 header
和一个 regexp
(它是 java 正则表达式)。此谓词匹配具有给定名称且其值与正则表达式匹配的标头。以下示例配置一个标头路由谓词:
spring:
cloud:
gateway:
mvc:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.header;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsCookie() {
return route("cookie_route")
.route(header("X-Request-Id", "\\d+"), http("https://example.org"))
.build();
}
}
如果请求具有名为 X-Request-Id
且其值与 \d+
正则表达式(即它具有一个或多个数字的值)匹配的标头,则此路由匹配。
The Host Request Predicate
Host
路由谓词工厂接受一个参数:主机名 patterns
的列表。该模式是一种具有 .
作为分隔符的 Ant 样式模式。此谓词匹配与该模式匹配的 Host
标头。以下示例配置一个 host 路由谓词:
spring:
cloud:
gateway:
mvc:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.host;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsHost() {
return route("host_route")
.route(host("**.somehost.org", "**.anotherhost.org"), http("https://example.org"))
.build();
}
}
还支持 URI 模板变量(例如 {sub}.myhost.org
)。
如果请求的 Host
标头的值为 www.somehost.org
或 beta.somehost.org
或 www.anotherhost.org
,则此路由匹配。
此谓词将 URI 模板变量(例如前一个示例中定义的 sub
)作为具有名称和值的地图提取出来,并使用 MvcUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
中定义的键将其置于 ServerRequest.attributes()
中。这样这些值就可以被 Gateway 处理程序筛选器函数使用了。
The Method Request Predicate
Method
请求谓词采用一个 methods
参数,该参数是一个或多个 HTTP 方法进行匹配。以下示例配置了方法路由谓词:
spring:
cloud:
gateway:
mvc:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
import org.springframework.http.HttpMethod;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.method;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsMethod() {
return route("method_route")
.route(method(HttpMethod.GET, HttpMethod.POST), http("https://example.org"))
.build();
}
}
此路由在请求方法为“GET”或“POST”时匹配。
GatewayRequestPredicates.method
是 RequestPredicates.methods
的一个简单别名。此外,RouterFunctions.Builder
API 包括将 method
和 path
RequestPredicates
相结合的便捷方法。
import org.springframework.http.HttpMethod;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.methods;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsMethod() {
return route("method_route")
.GET("/mypath", http("https://example.org"))
.build();
}
}
当请求方法是 GET
且路径是 /mypath
时,此路由就会匹配成功。
The Path Request Predicate
Path
Request Predicate 采用两个参数:Spring PathPattern
patterns
的列表。此 Request Predicate 使用 RequestPredicates.path()
作为底层实现。以下示例配置路径路由谓词:
spring:
cloud:
gateway:
mvc:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
import org.springframework.http.HttpMethod;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.method;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsPath() {
return route("path_route")
.route(path("/red/{segment}", "/blue/{segment}"), http("https://example.org"))
.build();
}
}
此路由在请求路径为 /red/1
或 /red/1/
或 /red/blue
或 /blue/green
时匹配。
此谓词将 URI 模板变量(例如前一个示例中定义的 segment
)作为具有名称和值的地图提取出来,并使用 RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE
中定义的键将其置于 ServerRequest.attributes()
中。这样这些值就可以被 Gateway 处理程序筛选器函数使用了。
提供了一个实用方法(称为 get
)以方便访问这些变量。以下示例展示了如何使用 get
方法:
Map<String, Object> uriVariables = MvcUtils.getUriTemplateVariables(request);
String segment = uriVariables.get("segment");
The Query Request Predicate
Query
路由谓词工厂采用两个参数:必需的 param
和可选的 regexp
(它是一个 Java 正则表达式)。以下示例配置了一个查询路由谓词:
spring:
cloud:
gateway:
mvc:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
import org.springframework.http.HttpMethod;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.query;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsQuery() {
return route("query_route")
.route(query("green"), http("https://example.org"))
.build();
}
}
如果请求包含一个名为“green”的查询参数,则上一个路由匹配。
spring:
cloud:
gateway:
mvc:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
import org.springframework.http.HttpMethod;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.query;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsQuery() {
return route("query_route")
.route(query("red", "gree."), http("https://example.org"))
.build();
}
}
如果请求包含一个名为“red”的查询参数且其值匹配 gree.
regexp,则上一个路由匹配,因此“green”和“greet”会匹配。
The Weight Request Predicate
Weight
路由谓词工厂采用两个参数:group
和 weight
(一个 int
)。权重是按组计算的。以下示例配置了权重路由谓词:
spring:
cloud:
gateway:
mvc:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
import org.springframework.http.HttpMethod;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.method;
@Configuration
class RouteConfiguration {
@Bean
public RouterFunction<ServerResponse> gatewayRouterFunctionsWeights() {
return route("weight_high")
.route(weight("group1", 8).and(path("/**")), http("https://weighthigh.org"))
.build().and(
route("weight_low")
.route(weight("group1", 2).and(path("/**")), http("https://weightlow.org"))
.build());
}
}
此路由将把约 80% 的流量转发到 [role="bare"][role="bare"]https://weighthigh.org,将约 20% 的流量转发到 [role="bare"][role="bare"]https://weightlow.org。