【Gateway】Route Predicate Factories

Spring Cloud Gateway 是一个功能强大的 API 网关框架,广泛用于微服务架构中。它的核心功能之一是路由请求,并根据规则将请求转发到目标服务。要实现这一功能,Spring Cloud Gateway 提供了各种断言工厂(Route Predicate Factories),用于定义和控制路由的行为。

1. Predicate

在编程中,Predicate 是一个常见的概念,主要用于对输入值进行判断或评估。它是一种返回布尔值(truefalse)的表达式或函数。在不同的编程语言和框架中,Predicate 的实现和应用可能有所不同,但核心思想是一致的:根据特定条件对输入进行判断。

在 Java 中,Predicate<T> 是一个函数式接口,用于接受类型为 T 的对象并返回一个布尔值。它是 Java 8 引入的函数式编程特性的一部分。

import java.util.function.Predicate;

public class PredicateExample {
    public static void main(String[] args) {
        Predicate<Integer> isEven = x -> x % 2 == 0;

        System.out.println(isEven.test(4)); // 输出: true
        System.out.println(isEven.test(5)); // 输出: false
    }
}

Predicate 下面还有其他逻辑,如“与”(AND)、“或”(OR)和“非”(NOT)操作。Predicate 接口提供了几个默认方法来实现这些逻辑操作:

1.1 and() 方法:与操作

  • 作用: 将两个 Predicate 组合起来,当且仅当两个 Predicate 都为 true 时,返回 true
  • 用法: predicate1.and(predicate2)
import java.util.function.Predicate;

public class PredicateAndExample {
    public static void main(String[] args) {
        Predicate<Integer> isEven = x -> x % 2 == 0;   // 判断是否为偶数
        Predicate<Integer> isPositive = x -> x > 0;   // 判断是否为正数

        Predicate<Integer> isEvenAndPositive = isEven.and(isPositive);

        System.out.println(isEvenAndPositive.test(4));  // 输出: true (4 是偶数且是正数)
        System.out.println(isEvenAndPositive.test(-4)); // 输出: false (-4 是偶数但不是正数)
    }
}

1.2 or() 方法:或操作

  • 作用: 将两个 Predicate 组合起来,当任意一个 Predicatetrue 时,返回 true
  • 用法: predicate1.or(predicate2)
import java.util.function.Predicate;

public class PredicateOrExample {
    public static void main(String[] args) {
        Predicate<Integer> isEven = x -> x % 2 == 0;  // 判断是否为偶数
        Predicate<Integer> isNegative = x -> x < 0;  // 判断是否为负数

        Predicate<Integer> isEvenOrNegative = isEven.or(isNegative);

        System.out.println(isEvenOrNegative.test(4));   // 输出: true (4 是偶数)
        System.out.println(isEvenOrNegative.test(-3));  // 输出: true (-3 是负数)
        System.out.println(isEvenOrNegative.test(3));   // 输出: false (3 既不是偶数也不是负数)
    }
}

1.3 negate() 方法:非操作

  • 作用: 返回与原 Predicate 相反的结果,即对结果进行取反。
  • 用法: predicate.negate()
import java.util.function.Predicate;

public class PredicateNegateExample {
    public static void main(String[] args) {
        Predicate<Integer> isEven = x -> x % 2 == 0; // 判断是否为偶数

        Predicate<Integer> isOdd = isEven.negate(); // 判断是否为奇数(取反)

        System.out.println(isOdd.test(4)); // 输出: false (4 是偶数)
        System.out.println(isOdd.test(5)); // 输出: true (5 是奇数)
    }
}
  • and() 用于组合多个 Predicate,要求所有条件都满足。
  • or() 用于组合多个 Predicate,只要有一个条件满足即可。
  • negate() 用于对 Predicate 结果取反。

 2. Route Predicate Factories

Route Predicate Factories(路由断言工厂,也称为路由谓词工厂,此处谓词表示一个函数),在SpringCloud Gateway中,Predicate提供了路由规则的匹配机制.

我们在配置文件中写的断言规则只是字符串,这些字符串会被Route Predicate Factory读取并处理,转变为路由判断的条件。比如,配置的 Path=/product/**,就是通过Path属性来匹配URL前缀是 /product 的请求.

Spring Cloud Gateway默认提供了很多Route Predicate Factory,这些Predicate会分别匹配HTTP请求的不同属性,并且多个Predicate可以通过and逻辑进行组合

更多内容见官网说明:

Route Predicate Factories :: Spring Cloud Gatewayicon-default.png?t=O83Ahttps://docs.spring.io/spring-cloud-gateway/reference/spring-cloud-gateway/request-predicates-factories.html

 

名称说明示例
After
这个⼯⼚需要⼀个⽇期时间(Java的 ZonedDateTime对象), 匹配指 定⽇期之后的请求
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

Before匹配指定日期前的请求
spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

Between
匹配两个指定时间之间的请求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]

Cookie
请求中包含指定Cookie, 且该Cookie值符合指定的正则表达式
spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=chocolate, ch.p

Header
请求中包含指定Header, 且该Header值符合指定的正则表达式
spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=X-Request-Id, \d+

Host
请求必须是访问某个host(根据请求中的Host
字段进⾏匹配)
spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: https://example.org
        predicates:
        - Host=**.somehost.org,**.anotherhost.org

Method
匹配指定的请求⽅式
spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET,POST

Path      
匹配指定规则的路径
spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: https://example.org
        predicates:
        - Path=/red/{segment},/blue/{segment}

Remote Addr
请求者的IP必须为指定范围
spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        - RemoteAddr=192.168.1.1/24

3. 演示

使用配置文件,设置路由必须是2024年9月12号xx之后的请求才可以访问。

server:
  port: 10040 # 网关端口
spring:
  application:
    name: gateway # 服务名称
  cloud:
    nacos:
      discovery:
        server-addr: ip:8848
        namespace: fcc2c221-085b-4864-bff4-f1f18f734cb0
    gateway:
      routes: # 网关路由配置
        - id: product-service # 路由ID, 自定义, 唯一即可
          uri: lb://product-service # 目标服务地址
          predicates: # 路由条件
            - Path=/product/**
            - After=2024-09-12T17:42:47.789-07:00[America/Denver]
        - id: order-service
          uri: lb://order-service
          predicates:
            - Path=/order/**

测试,访问 http://127.0.0.1:10040/product/1001

修改配置文件,设置为2024年9月20号xx之后的请求才可以访问。(现在访问不了)

使用 Route Predicate Factories 可以灵活地根据请求的各种属性来匹配和路由请求,实现微服务架构中的动态路由功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小小小小关同学

你的支持就是我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值