Gateway Between 路由断言工厂

Between 路由断言工厂需要两个参数:datetime1 和 datetime2,它们都是 java ZonedDateTime 对象。语法如下:

Between=datetime1, datetime2

该断言匹配发生在 datetime1 之后和日期 datetime2 之前的请求,datetime2 参数必须在 datetime1 之后。例如:

spring:
 cloud:
   gateway:
     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]

上面配置中,between_route 路由将仅仅接收 2017年1月20日 17:42 山地时间(Denver 丹佛)之后至 2017年1月21日 17:42 山地时间(Denver 丹佛)之前提出的任何请求。

示例

将“Gateway 搭建网关服务”项目的配置文件 bootstrap.yml 内容使用如下配置替换:

server:
  # 网关端口
  port: 9000

spring:
  application:
    # 服务名称
    name: gateway-demo01
  cloud:
    # nacos
    nacos:
      discovery:
        server-addr: localhost:8848
        username: nacos
        password: nacos
        group: DEFAULT_GROUP

    # 网关路由配置
    gateway:
      # 网关路由配置
      routes:
        # 路由id,自定义,只要唯一集合
        - id: service-order
          # 路由的目标地址,lb 就是负载均衡,后面跟服务名
          # 需要集成 nacos 等服务注册中心
          uri: lb://service-order
          # 路由断言,也就是判断请求是否符合路由规则的条件
          predicates:
            # Between断言:匹配 2023-12-09 22点~23点之间的请求
            - Between=2023-12-09T22:00:00.000-08:00[Asia/Shanghai],2023-12-09T23:00:00.000-08:00[Asia/Shanghai]

重启网关服务,使用 Postman 访问订单接口,如下图:

Gateway Between 路由断言工厂

从上图可知,请求成功,因为当前时间为 2023-12-09 22:15:00。如果我们将配置修改为如下:

- Between=2023-12-09T22:00:00.000-08:00[Asia/Shanghai],2023-12-09T22:15:00.000-08:00[Asia/Shanghai]

再次重启网关服务,访问订单接口如下图:

Gateway Between 路由断言工厂

从上图可知,调用失败,为当前时间并不在 2023-12-09 22:00 ~ 2023-12-09 22:15 之间。

源码分析

下面是 Between 路由断言工厂源码:

package org.springframework.cloud.gateway.handler.predicate;

// ...

public class BetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<BetweenRoutePredicateFactory.Config> {

    public static final String DATETIME1_KEY = "datetime1";
    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) {
       // 获取配置的日期
       ZonedDateTime datetime1 = config.datetime1;
       ZonedDateTime datetime2 = config.datetime2;
       
       // 验证 datetime1 必须在 datetime2 之前
       Assert.isTrue(datetime1.isBefore(datetime2),
             config.datetime1 +
             " must be before " + config.datetime2);

       return exchange -> {
          // 根据当前日期进行计算
          // datetime1 < now < datetime2
          final ZonedDateTime now = ZonedDateTime.now();
          return now.isAfter(datetime1) && now.isBefore(datetime2);
       };
    }

    @Validated
    public static class Config {
       @NotNull
       private ZonedDateTime datetime1;
       @NotNull
       private ZonedDateTime datetime2;

       // 配置信息
    }

}
说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号