网关请求谓词

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)。此谓词匹配在指定日期时间之后发生的请求。以下示例配置了一个 After 路由谓词。

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: after_route
          uri: https://example.org
          predicates:
          - After=2017-01-20T17:42:47.789-07:00[America/Denver]
GatewaySampleApplication.java
import java.time.ZonedDateTime;
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
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())
            .before(uri("https://example.org"))
            .build();
    }
}

此路由匹配在 2017 年 1 月 20 日 17:42(丹佛山区时间)之后发出的任何请求。

Before 请求谓词

Before 路由谓词工厂接受一个参数,即 datetime(一个 Java ZonedDateTime)。此谓词匹配在指定 datetime 之前发生的请求。以下示例配置了一个 Before 路由谓词。

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: before_route
          uri: https://example.org
          predicates:
          - Before=2017-01-20T17:42:47.789-07:00[America/Denver]
GatewaySampleApplication.java
import java.time.ZonedDateTime;
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
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()
            .before(uri("https://example.org"))
            .build();
    }
}

此路由匹配在 2017 年 1 月 20 日 17:42(丹佛山区时间)之前发出的任何请求。

Between 请求谓词

Between 路由谓词工厂接受两个参数:datetime1datetime2,它们都是 Java ZonedDateTime 对象。此谓词匹配在 datetime1 之后且在 datetime2 之前发生的请求。参数 datetime2 必须在 datetime1 之后。以下示例配置了一个 Between 路由谓词。

application.yml
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]
GatewaySampleApplication.java
import java.time.ZonedDateTime;
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
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())
            .before(uri("https://example.org"))
            .build();
    }
}

此路由匹配在 2017 年 1 月 20 日 17:42(丹佛山区时间)之后且在 2017 年 1 月 21 日 17:42(丹佛山区时间)之前发出的任何请求。这可能对维护窗口有用。

Cookie 路由谓词工厂接受两个参数:Cookie name 和一个 regexp(一个 Java 正则表达式)。此谓词匹配具有给定名称且其值与正则表达式匹配的 Cookie。以下示例配置了一个 Cookie 路由谓词工厂。

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: cookie_route
          uri: https://example.org
          predicates:
          - Cookie=chocolate, ch.p
GatewaySampleApplication.java
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
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.cookie;

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouterFunctionsCookie() {
        return route("cookie_route")
            .route(cookie("chocolate", "ch.p"), http())
            .before(uri("https://example.org"))
            .build();
    }
}

此路由匹配具有名为 chocolate 的 Cookie 且其值与 ch.p 正则表达式匹配的请求。

Header 请求谓词

Header 路由谓词工厂接受两个参数:header 和一个 regexp(一个 Java 正则表达式)。此谓词匹配具有给定名称且其值与正则表达式匹配的 Header。以下示例配置了一个 Header 路由谓词。

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: header_route
          uri: https://example.org
          predicates:
          - Header=X-Request-Id, \d+
GatewaySampleApplication.java
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
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> gatewayRouterFunctionsHeader() {
        return route("header_route")
            .route(header("X-Request-Id", "\\d+"), http())
            .before(uri("https://example.org"))
            .build();
    }
}

如果请求具有名为 X-Request-Id 的 Header 且其值与 \d+ 正则表达式(即,其值为一个或多个数字)匹配,则此路由匹配。

Host 请求谓词

Host 路由谓词工厂接受一个参数:主机名 patterns 列表。该模式是一个以 . 作为分隔符的 Ant 风格模式。此谓词匹配与模式匹配的 Host Header。以下示例配置了一个 Host 路由谓词。

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: host_route
          uri: https://example.org
          predicates:
          - Host=**.somehost.org,**.anotherhost.org
GatewaySampleApplication.java
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
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())
            .before(uri("https://example.org"))
            .build();
    }
}

URI 模板变量(例如 {sub}.myhost.org)也受支持。

如果请求具有 Host Header,其值为 www.somehost.orgbeta.somehost.orgwww.anotherhost.org,则此路由匹配。

此谓词将 URI 模板变量(例如上例中定义的 sub)提取为名称和值的映射,并将其放置在 ServerRequest.attributes() 中,其键由 MvcUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE 定义。这些值随后可供网关处理器过滤函数使用。

Method 请求谓词

Method 请求谓词接受一个 methods 参数,该参数是一个或多个 HTTP 方法,用于匹配。以下示例配置了一个方法路由谓词。

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: method_route
          uri: https://example.org
          predicates:
          - Method=GET,POST
GatewaySampleApplication.java
import org.springframework.http.HttpMethod;
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
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())
            .before(uri("https://example.org"))
            .build();
    }
}

如果请求方法是 GETPOST,则此路由匹配。

GatewayRequestPredicates.methodRequestPredicates.methods 的简单别名。此外,RouterFunctions.Builder API 包含组合 methodpath RequestPredicates 的便捷方法。

GatewaySampleApplication.java
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
import static org.springframework.cloud.gateway.server.mvc.handler.GatewayRouterFunctions.route;
import static org.springframework.cloud.gateway.server.mvc.handler.HandlerFunctions.http;

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouterFunctionsMethodAndPath() {
        return route("method_and_path_route")
            .GET("/mypath", http())
            .before(uri("https://example.org"))
            .build();
    }
}

如果请求方法是 GET 且路径是 /mypath,则此路由匹配。

Path 请求谓词

Path 请求谓词接受两个参数:Spring PathPattern patterns 列表。此请求谓词使用 RequestPredicates.path() 作为底层实现。以下示例配置了一个路径路由谓词。

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: path_route
          uri: https://example.org
          predicates:
          - Path=/red/{segment},/blue/{segment}
GatewaySampleApplication.java
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
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.path;

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouterFunctionsPath() {
        return route("path_route")
            .route(path("/red/{segment}", "/blue/{segment}"), http())
            .before(uri("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 正则表达式)。以下示例配置了一个查询路由谓词。

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: query_route
          uri: https://example.org
          predicates:
          - Query=green
GatewaySampleApplication.java
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
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())
            .before(uri("https://example.org"))
            .build();
    }
}

如果请求包含 green 查询参数,则上述路由匹配。

application.yml
spring:
  cloud:
    gateway:
      mvc:
        routes:
        - id: query_route
          uri: https://example.org
          predicates:
          - Query=red, gree.
GatewaySampleApplication.java
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
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())
            .before(uri("https://example.org"))
            .build();
    }
}

如果请求包含 red 查询参数,且其值与 gree. 正则表达式匹配,例如 greengreet,则上述路由匹配。

Weight 请求谓词

Weight 路由谓词工厂接受两个参数:groupweight(一个 int)。权重按组计算。以下示例配置了一个权重路由谓词。

application.yml
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
GatewaySampleApplication.java
import static org.springframework.cloud.gateway.server.mvc.filter.BeforeFilterFunctions.uri;
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.path;
import static org.springframework.cloud.gateway.server.mvc.predicate.GatewayRequestPredicates.weight;

@Configuration
class RouteConfiguration {

	@Bean
	public RouterFunction<ServerResponse> gatewayRouterFunctionsWeights() {
        return route("weight_high")
                .route(weight("group1", 8).and(path("/**")), http())
                .before(uri("https://weighthigh.org"))
                .build().and(
            route("weight_low")
                .route(weight("group1", 2).and(path("/**")), http())
                .before(uri("https://weightlow.org"))
                .build());
	}
}

此路由会将约 80% 的流量转发到 weighthigh.org,将约 20% 的流量转发到 weightlow.org

© . This site is unofficial and not affiliated with VMware.