欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

12.gateway中的断言(predicate)的使用:内置断言介绍、自定义断言

程序员文章站 2022-03-04 23:02:22
...

Predicate(断言, 谓词) 用于进行条件判断,只有断言都返回真,才会真正的执行路由。

断言就是说: 在 什么条件下 才能进行路由转发

内置断言工厂

SpringCloud Gateway包括许多内置的断言工厂,所有这些断言都与HTTP请求的不同属性匹配体如下: 都是使用在 predicates: 下的


1.基于Datetime类型的断言工厂

此类型的断言根据时间做判断,主要有三个:

  • AfterRoutePredicateFactory: 接收一个日期参数,判断请求日期是否晚于指定日期
  • BeforeRoutePredicateFactory: 接收一个日期参数,判断请求日期是否早于指定日期
  • BetweenRoutePredicateFactory: 接收两个日期参数,判断请求日期是否在指定时间段内

使用方式:

spring:
  cloud:
    gateway:
      routes:
        - id: shop-product            # 路由的唯一标识
          uri: lb://shop-product      # 如果断言成功,将要转发去的地址
          order: 0                    # 优先级,越小优先级越高
          predicates:                 # 断言,满足所有断言,才会进行转发
          	# 在这个时间之后才能进行访问
            - After=2019-12-31T23:59:59.789+08:00[Asia/Shanghai]  

2. 基于远程地址的断言工厂

  • RemoteAddrRoutePredicateFactory: 接收一个IP地址段,判断请求主机地址是否在地址段中
- RemoteAddr=192.168.1.1/24 

3. 基于Cookie的断言工厂

  • CookieRoutePredicateFactory:接收两个参数,cookie 名字和一个正则表达式。 判断请求cookie是否具有给定名称且值与正则表达式匹配。
- Cookie=chocolate, ch.

4. 基于Header的断言工厂

  • HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式。 判断请求Header是否具有给定名称且值与正则表达式匹配。
- Header=X-Request-Id, \d+

5.基于Host的断言工厂

  • HostRoutePredicateFactory:接收一个参数,主机名模式。判断请求的Host是否满足匹配规则。
- Host=**.testhost.org

6.基于Method请求方法的断言工厂

  • MethodRoutePredicateFactory:接收一个参数,判断请求类型是否跟指定的类型匹配。
- Method=GET

7.基于Path请求路径的断言工厂

  • PathRoutePredicateFactory:接收一个参数,判断请求的URI部分是否满足路径规则。
- Path=/foo/{segment}

8.基于Query请求参数的断言工厂

  • QueryRoutePredicateFactory :接收两个参数,请求param和正则表达式, 判断请求参数是否具有给定名称且值与正则表达式匹配。
- Query=baz, ba. 

9.基于路由权重的断言工厂

  • WeightRoutePredicateFactory:接收一个 [组名,权重] 然后对于同一个组内的路由按照权重转发
gateway:
  routes:
  - id: weight_route1
    uri: host1
    predicates:
      - Path=/product/**
      - Weight=group3, 1
  - id: weight_route2
    uri: host2
    predicates:
      # 路径一致,组一致,权重不同
      - Path=/product/**
      - Weight= group3, 9

自定义路由断言工厂

我们来设定一个场景: 假设我们的应用仅仅让age在(min,max)之间的人来访问。
使用例子来体验一把自定义路由断言工厂

1.定义一个断言工厂,实现断言方法

新建一个类,继承 AbstractRoutePredicateFactory 类,这个类的泛型是 自定义断言工厂的一个内部类叫做Config 是一个固定的名字,在Config 类中定义自定义断言需要的一些属性,并且自定义断言工厂使用 @Component 注解,交给spring容器创建

这里的age是通过请求参数(request.getQueryParams())获取的,这个可以根据需要进行调整。你需要从请求头获取,就通过request.getHeaders() 获取即可。

@Component
public class AgeRoutePredicateFactory extends AbstractRoutePredicateFactory<AgeRoutePredicateFactory.Config> {
    public AgeRoutePredicateFactory() {
        super(AgeRoutePredicateFactory.Config.class);
    }

    //读取配置文件中的内容并配置给配置类中的属性
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("minAge","maxAge");
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return exchange -> {
            // 获取请求参数中的 age 属性
            String age = exchange.getRequest().getQueryParams().getFirst("age");
            if(StringUtils.isNotEmpty(age)) {
                try {
                    int a = Integer.parseInt(age);
                    boolean res = a >= config.minAge && a <= config.maxAge;
                    return res;
                } catch (Exception e) {
                    System.out.println("输入的参数不是数字格式");
                }
            }
            return false;
        };
    }

    @Validated
    public static class Config {
        private Integer minAge;
        private Integer maxAge;

        public Integer getMinAge() {
            return minAge;
        }

        public void setMinAge(Integer minAge) {
            this.minAge = minAge;
        }

        public Integer getMaxage() {
            return maxAge;
        }

        public void setMaxage(Integer maxage) {
            this.maxAge = maxage;
        }
    }
}

在这个自定义断言中,.Config 中有两个属性 minAge 和 maxAge
apply() 方法中编写断言的比较逻辑

2. 在yml中使用自定义断言

在yml文件中使用自定义断言。

spring:
  cloud:
    gateway:
      routes:
        - id: shop-product            # 路由的唯一标识
          uri: lb://shop-product      # 如果断言成功,将要转发去的地址
          order: 0                    # 优先级,越小优先级越高
          predicates:                 # 断言,满足所有断言,才会进行转发
            - Path=/product/**        # 注意:这是使用= 不是:
            # 自定义断言,第一个参数对应minAge,第二个参数对应maxAge
            - Age=18, 60

从这里的演示应该可以看出来,自定义断言与系统自带断言的配置,在yml中只需要使用首部名称,默认忽略类名中的 RoutePredicateFactory

例如自定义的断言 AgeRoutePredicateFactory 在使用的时候,就是通过 -Age 进行指定的。



效果:
12.gateway中的断言(predicate)的使用:内置断言介绍、自定义断言
12.gateway中的断言(predicate)的使用:内置断言介绍、自定义断言

ok,就是这样