閘道請求斷言
Spring Cloud Gateway MVC 將路由比對作為 Spring WebMvc.fn HandlerMapping
基礎架構的一部分。Spring Cloud Gateway 重複使用了 WebMvc.fn 中的許多 RequestPredicate
實作,並包含其他自訂的 RequestPredicate
實作。所有這些斷言都比對 HTTP 請求的不同屬性。您可以將多個路由斷言工廠與 RequestPredicate.and()
和 RequestPredicate.or()
方法結合使用。
After 請求斷言
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 山區時間(丹佛)之後發出的任何請求。
Before 請求斷言
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 山區時間(丹佛)之前發出的任何請求。
Between 請求斷言
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 山區時間(丹佛)之前發出的任何請求。這對於維護視窗可能很有用。
Cookie 請求斷言
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
正則表達式匹配的請求。
Header 請求斷言
Header
路由斷言工廠接受兩個參數,header
和 regexp
(Java 正則表達式)。此斷言比對具有給定名稱且其值與正則表達式匹配的標頭。以下範例設定了一個 header 路由斷言
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+
正則表達式(即,它具有一個或多個數字的值)匹配,則此路由會匹配。
Host 請求斷言
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
)作為名稱和值的映射,並將其放置在 ServerRequest.attributes()
中,並使用 MvcUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
中定義的鍵。這些值隨後可供閘道處理器篩選器函數使用。
Method 請求斷言
Method
請求斷言接受 methods
參數,它是一個或多個參數:要比對的 HTTP 方法。以下範例設定了一個 method 路由斷言
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
,則此路由會匹配。
Path 請求斷言
Path
請求斷言接受兩個參數:Spring PathPattern
patterns
的列表。此請求斷言使用 RequestPredicates.path()
作為底層實作。以下範例設定了一個 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
)作為名稱和值的映射,並將其放置在 ServerRequest.attributes()
中,並使用 RouterFunctions.URI_TEMPLATE_VARIABLES_ATTRIBUTE
中定義的鍵。這些值隨後可供閘道處理器篩選器函數使用。
一個公用程式方法(稱為 get
)可用於更輕鬆地存取這些變數。以下範例示範如何使用 get
方法
Map<String, Object> uriVariables = MvcUtils.getUriTemplateVariables(request);
String segment = uriVariables.get("segment");
Query 請求斷言
Query
路由斷言工廠接受兩個參數:必要的 param
和可選的 regexp
(Java 正則表達式)。以下範例設定了一個 query 路由斷言
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
會匹配。
Weight 請求斷言
Weight
路由斷言工廠接受兩個參數:group
和 weight
(int
)。權重是按群組計算的。以下範例設定了一個 weight 路由斷言
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% 的流量轉發到 weighthigh.org,將約 20% 的流量轉發到 weightlow.org。