Spring Cloud Gateway之Predicate断言详解

目录

Predicate(断言)

在 Spring Cloud Gateway 中,Predicate(断言)是用于匹配传入请求的条件。它们用于确定哪些请求应该被路由到特定的目标服务。

Predicate 接受一个输入参数,返回一个布尔值结果。该接口包含多种默认方法来将 Predicate 组合成其他复杂的逻辑(比如:与,或,非)。

Spring Cloud Gateway 提供了多种预定义的 Predicate,可以根据不同的条件进行路由匹配。以下是一些常用的 Predicate

内置Predicate

请求参数匹配

Query Route Predicate 支持传入两个参数,一个是属性名一个为属性值,属性值可以是正则表达式。

示例:

powershell 复制代码
spring:
  cloud:
    gateway:
      routes:
      - id: my_route
        uri: https://example.org
        predicates:
        - Query=myparameter

这样配置,只要请求中包含 myparameter属性的参数即可匹配路由。

我们还可以对参数值也进行配置

java 复制代码
spring:
  cloud:
    gateway:
      routes:
      - id: my_route
        uri: https://example.org
        predicates:
        - Query=myparameter,parametervalue

这样配置, myparameter属性的值为parametervalue才会匹配

同时我们还可以使用正则表达式来表示

java 复制代码
        predicates:
        - Query=myparameter,my.

这样只要当请求中包含 myparameter属性并且参数值是以 my 开头的长度为三位的字符串才会进行匹配和路由。

请求路径匹配

Path Route Predicate 接收一个匹配路径的参数来判断是否走路由。

java 复制代码
spring:
  cloud:
    gateway:
      routes:
      - id: my_route
        uri: https://example.org
        predicates:
        - Path=/user/**

这样设置,则/user开头的任一路径都会匹配路由

在路径配置中,我们可以使用{segment}来进行占位,表示一个请求路径中的特定段

具体来说,{segment}可以用于匹配请求路径中的任意段。例如,如果有一个路由路径定义为/api/{segment}/users,那么当请求路径为/api/profile/users时,{segment}将会被替换为profile,从而匹配该路由路径。

但是{segment}不支持匹配子路径,如果想匹配子路径需要使用/**

Header 属性匹配

Header Route Predicate 接受两个参数:一个 header 中属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行

java 复制代码
spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: https://example.org
        predicates:
        - Header=X-Request-Id, \d+

这样配置,则只有header请求头中有X-Request-Id属性,并且属性值为数值的时候才匹配路由

Cookie Route Predicate 可以接收两个参数,一个是 Cookie name ,一个是正则表达式,路由规则会通过获取对应的 Cookie name 值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行。

java 复制代码
spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=chocolate, ch.p

这样配置,请求必须包含一个名为chocolate的cookie,其值需要与ch.p正则表达式匹配才会进行路由

请求方式匹配

可以通过是 POST、GET、PUT、DELETE 等不同的请求方式来进行路由,支持一个或多个参数

java 复制代码
spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=GET,POST

这样配置,如果请求方法是GET或POST,则此路由匹配

请求 ip 地址匹配

Predicate 也支持通过设置某个 ip 区间号段的请求才会路由,RemoteAddr Route Predicate 接受 cidr 符号(IPv4 或 IPv6 )字符串的列表(最小大小为1),例如 192.168.0.1/16 (其中 192.168.0.1 是 IP 地址,16 是子网掩码)。

在 CIDR 表示法中,IP 地址后面跟着斜杠和一个数字,斜杠后的数字表示子网掩码位数。

CIDR 符号的范围从 /0 到 /32,对应着不同长度的子网掩码位数。较小的数字表示更大的范围,例如 /0 表示整个 IP 地址空间,而 /32 表示单个主机地址。

java 复制代码
spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: https://example.org
        predicates:
        - RemoteAddr=192.168.1.1/24

192.168.1.1/24 表示一个 CIDR 格式的 IP 地址范围,其中 /24 表示子网掩码。这个范围包括从 192.168.1.1 到 192.168.1.254 的所有 IP 地址。例如,如果请求的远端地址为192.168.1.10,则此路由匹配。

如果你只想匹配单个ip地址,那么可以使用ip/32来表示,ip/32表示只有该 IP 地址本身才会匹配,其他任何 IP 地址都不会与之匹配。

时间匹配

我们可以指定某个时间前后的请求匹配路由

After :匹配在指定日期时间之后发生的请求

java 复制代码
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

如果想匹配某个日期之前,那么可以使用Before

java 复制代码
spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: https://example.org
        predicates:
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

组合匹配

多个 Predicates 可以同时存在于同一个路由,请求必须同时满足所有的条件才被这个路由匹配

示例

java 复制代码
spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: https://example.org
        predicates:
        - Method=POST
        - Header=X-Request-Id, \d+

这样配置,只有当请求方法是POST方法,而且请求头有X-Request-Id属性,且值为数值才会匹配

相关推荐
Yan.love5 分钟前
开发场景中Java 集合的最佳选择
java·数据结构·链表
椰椰椰耶8 分钟前
【文档搜索引擎】搜索模块的完整实现
java·搜索引擎
大G哥8 分钟前
java提高正则处理效率
java·开发语言
小_太_阳30 分钟前
Scala_【1】概述
开发语言·后端·scala·intellij-idea
智慧老师39 分钟前
Spring基础分析13-Spring Security框架
java·后端·spring
lxyzcm41 分钟前
C++23新特性解析:[[assume]]属性
java·c++·spring boot·c++23
V+zmm101341 小时前
基于微信小程序的乡村政务服务系统springboot+论文源码调试讲解
java·微信小程序·小程序·毕业设计·ssm
Oneforlove_twoforjob2 小时前
【Java基础面试题025】什么是Java的Integer缓存池?
java·开发语言·缓存
xmh-sxh-13142 小时前
常用的缓存技术都有哪些
java
搬码后生仔2 小时前
asp.net core webapi项目中 在生产环境中 进不去swagger
chrome·后端·asp.net