Gateway Request Predicates
Spring Cloud Gateway MVC 作为 Spring WebMvc.fn HandlerMapping
基础架构的一部分匹配路由。Spring Cloud Gateway 重用了 WebMvc.fn 中的许多 RequestPredicate
实现,并包含其他自定义 RequestPredicate
实现。所有这些谓词都匹配 HTTP 请求的不同属性。您可以使用 RequestPredicate.and()
和 RequestPredicate.or()
方法组合多个路由谓词工厂。
Spring Cloud Gateway MVC matches routes as part of the Spring WebMvc.fn HandlerMapping
infrastructure.
Spring Cloud Gateway reuses many RequestPredicate
implementations from WebMvc.fn and includes other custom RequestPredicate
implementations
All of these predicates match on different attributes of the HTTP request.
You can combine multiple route predicate factories with the RequestPredicate.and()
and RequestPredicate.or()
methods.
The After Request Predicate
After
路由谓词工厂接受一个参数,即一个 datetime
(它是 java ZonedDateTime
)。此谓词匹配在指定 datetime 之后发生的请求。以下示例配置一个 after 路由谓词:
The After
route predicate factory takes one parameter, a datetime
(which is a java ZonedDateTime
).
This predicate matches requests that happen after the specified datetime.
The following example configures an after route predicate:
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 山地时间(丹佛)之后发送的任何请求。
This route matches any request made after Jan 20, 2017 17:42 Mountain Time (Denver).
The Before Request Predicate
Before
路由谓词工厂接受一个参数,即一个 datetime
(它是 java ZonedDateTime
)。此谓词匹配在指定 datetime
之前发生的请求。以下示例配置一个 before 路由谓词:
The Before
route predicate factory takes one parameter, a datetime
(which is a java ZonedDateTime
).
This predicate matches requests that happen before the specified datetime
.
The following example configures a before route predicate:
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 山地时间(丹佛)之前发送的任何请求。
This route matches any request made before Jan 20, 2017 17:42 Mountain Time (Denver).
The Between Request Predicate
Between
路由谓词工厂接受两个参数,它们是 datetime1
和 datetime2
,它们是 java ZonedDateTime
对象。此谓词匹配在 datetime1
之后和在 datetime2
之前发生的请求。datetime2
参数必须在 datetime1
之后。以下示例配置一个 between 路由谓词:
The Between
route predicate factory takes two parameters, datetime1
and datetime2
which are java ZonedDateTime
objects.
This predicate matches requests that happen after datetime1
and before datetime2
.
The datetime2
parameter must be after datetime1
.
The following example configures a between route predicate:
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 山地时间(丹佛)之前发生的任何请求。这对于维护窗口可能很有用。
This route matches any request made after Jan 20, 2017 17:42 Mountain Time (Denver) and before Jan 21, 2017 17:42 Mountain Time (Denver). This could be useful for maintenance windows.
The Cookie Request Predicate
Cookie
路由谓词工厂接受两个参数,即 Cookie name
和一个 regexp
(它是 java 正则表达式)。此谓词匹配具有给定名称且其值与正则表达式匹配的 Cookie。以下示例配置一个 cookie 路由谓词工厂:
The Cookie
route predicate factory takes two parameters, the cookie name
and a regexp
(which is a Java regular expression).
This predicate matches cookies that have the given name and whose values match the regular expression.
The following example configures a cookie route predicate factory:
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
正则表达式匹配的请求。
This route matches requests that have a cookie named chocolate
whose value matches the ch.p
regular expression.
The Header Request Predicate
Header
路由谓词工厂接受两个参数,即 header
和一个 regexp
(它是 java 正则表达式)。此谓词匹配具有给定名称且其值与正则表达式匹配的标头。以下示例配置一个标头路由谓词:
The Header
route predicate factory takes two parameters, the header
and a regexp
(which is a Java regular expression).
This predicate matches with a header that has the given name whose value matches the regular expression.
The following example configures a header route predicate:
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+
正则表达式(即它具有一个或多个数字的值)匹配的标头,则此路由匹配。
This route matches if the request has a header named X-Request-Id
whose value matches the \d+
regular expression (that is, it has a value of one or more digits).
The Host Request Predicate
Host
路由谓词工厂接受一个参数:主机名 patterns
的列表。该模式是一种具有 .
作为分隔符的 Ant 样式模式。此谓词匹配与该模式匹配的 Host
标头。以下示例配置一个 host 路由谓词:
The Host
route predicate factory takes one parameter: a list of host name patterns
.
The pattern is an Ant-style pattern with .
as the separator.
This predicates matches the Host
header that matches the pattern.
The following example configures a host route predicate:
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
)。
URI template variables (such as {sub}.myhost.org
) are supported as well.
如果请求的 Host
标头的值为 www.somehost.org
或 beta.somehost.org
或 www.anotherhost.org
,则此路由匹配。
This route matches if the request has a Host
header with a value of www.somehost.org
or beta.somehost.org
or www.anotherhost.org
.
此谓词将 URI 模板变量(例如前一个示例中定义的 sub
)作为具有名称和值的地图提取出来,并使用 MvcUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
中定义的键将其置于 ServerRequest.attributes()
中。这样这些值就可以被 Gateway 处理程序筛选器函数使用了。
This predicate extracts the URI template variables (such as sub
, defined in the preceding example) as a map of names and values and places it in the ServerRequest.attributes()
with a key defined in MvcUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
.
Those values are then available for use by Gateway Handler Filter Functions.
The Method Request Predicate
Method
请求谓词采用一个 methods
参数,该参数是一个或多个 HTTP 方法进行匹配。以下示例配置了方法路由谓词:
The Method
Request Predicate takes a methods
argument which is one or more parameters: the HTTP methods to match.
The following example configures a method route predicate:
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”时匹配。
This route matches if the request method was a GET
or a POST
.
GatewayRequestPredicates.method
是 RequestPredicates.methods
的一个简单别名。此外,RouterFunctions.Builder
API 包括将 method
和 path
RequestPredicates
相结合的便捷方法。
GatewayRequestPredicates.method
is a simple alias for RequestPredicates.methods
. Also, the RouterFunctions.Builder
API includes convenience methods that combine the method
and 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
时,此路由就会匹配成功。
This route matches if the request method was a GET
and the path was /mypath
.
The Path Request Predicate
Path
Request Predicate 采用两个参数:Spring PathPattern
patterns
的列表。此 Request Predicate 使用 RequestPredicates.path()
作为底层实现。以下示例配置路径路由谓词:
The Path
Request Predicate takes two parameters: a list of Spring PathPattern
patterns
.
This Request Predicate uses RequestPredicates.path()
as the underlying implementation.
The following example configures a path route predicate:
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
时匹配。
This route matches if the request path was, for example: /red/1
or /red/1/
or /red/blue
or /blue/green
.
此谓词将 URI 模板变量(例如前一个示例中定义的 segment
)作为具有名称和值的地图提取出来,并使用 RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE
中定义的键将其置于 ServerRequest.attributes()
中。这样这些值就可以被 Gateway 处理程序筛选器函数使用了。
This predicate extracts the URI template variables (such as segment
, defined in the preceding example) as a map of names and values and places it in the ServerRequest.attributes()
with a key defined in RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE
.
Those values are then available for use by Gateway Handler Filter Functions.
提供了一个实用方法(称为 get
)以方便访问这些变量。以下示例展示了如何使用 get
方法:
A utility method (called get
) is available to make access to these variables easier.
The following example shows how to use the get
method:
Map<String, Object> uriVariables = MvcUtils.getUriTemplateVariables(request);
String segment = uriVariables.get("segment");
The Query Request Predicate
Query
路由谓词工厂采用两个参数:必需的 param
和可选的 regexp
(它是一个 Java 正则表达式)。以下示例配置了一个查询路由谓词:
The Query
route predicate factory takes two parameters: a required param
and an optional regexp
(which is a Java regular expression).
The following example configures a query route predicate:
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”的查询参数,则上一个路由匹配。
The preceding route matches if the request contained a green
query parameter.
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 preceding route matches if the request contained a red
query parameter whose value matched the gree.
regexp, so green
and greet
would match.
The Weight Request Predicate
Weight
路由谓词工厂采用两个参数:group
和 weight
(一个 int
)。权重是按组计算的。以下示例配置了权重路由谓词:
The Weight
route predicate factory takes two arguments: group
and weight
(an int
). The weights are calculated per group.
The following example configures a weight route predicate:
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。
This route would forward ~80% of traffic to [role="bare"]https://weighthigh.org and ~20% of traffic to [role="bare"]https://weightlow.org.