spring cloud gateway内置路由断言工厂

简介

在spring cloud gateway中有支持以服务名为开头的默认路由规则,但是在实际生产中的路由规则可能更复杂,需要支持自定义的路由规则定义,包括路径匹配、时间匹配、请求匹配等等,以下是spring cloud gateway内置的路由断言工厂及一般用法

内置断言工厂

spring cloud gateway内置的路由断言工厂在使用的使用是通过名称完成映射的,路由断言工厂的命名规则如下:xxxRoutePredicateFactory,所以在使用的时候只需要指定名称即可完成映射使用,比如:PathRoutePredicateFactory,在使用的时候只需要指定Path即可

PathRoutePredicateFactory

请求路径断言工厂,根据请求路径断言是否命中,最常用的断言工厂

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      locator:
        enabled: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**,/sc-consumer/**
          filters:
            - StripPrefix=1

多个路径用逗号隔开即可,对于多个配置路径,只要有一个匹配即命中

AfterRoutePredicateFactory

after断言工厂表示请求只有在xxx时间之后才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - After=2025-12-26T12:00:00+08:00[Asia/Shanghai] #时间过滤器,只允许在指定时间之后的请求
          filters:
            - StripPrefix=1
   

这里的路由配置了两个断言规则,只有2个断言规则均匹配时才能命中

BeforeRoutePredicateFactory

before断言工厂表示请求只有在xxx时间之前才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Before=2025-12-26T12:00:00+08:00[Asia/Shanghai] #时间过滤器,只允许在指定时间之后的请求
          filters:
            - StripPrefix=1

BetweenRoutePredicateFactory

between断言工厂表示请求只有在xxx1时间和xxx2时间之间才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Between=2025-12-26T16:00:00+08:00[Asia/Shanghai], 2025-12-26T16:15:00+08:00[Asia/Shanghai]
          filters:
            - StripPrefix=1
   

配置需要2个参数,只有逗号隔开

CookieRoutePredicateFactory

cookie断言工厂表示请求只有携带了某个cookie值满足条件时请求才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Cookie=need-trace,123456
          filters:
            - StripPrefix=1
   

cookie断言工厂的匹配模式是基于String的matchs方法实现的,实际生产中可能会配置更复杂的匹配正则表达式

HeaderRoutePredicateFactory

header断言工厂表示请求只有携带了某个header且值满足条件时请求才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Header=need-trace,123456
          filters:
            - StripPrefix=1
   

HostRoutePredicateFactory

host断言工厂表示请求头中的Host的值满足条件时请求才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Host=192.168.56.*
          filters:
            - StripPrefix=1
   

MethodRoutePredicateFactory

method断言工厂表示用对应的method发起请求时才能通过断言

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Method=get
          filters:
            - StripPrefix=1
   

QueryRoutePredicateFactory

Query断言工厂表示发起请求的url中必须要携带的请求参数,且参数值匹配正则才能命中

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Query=userName,zhangsan*
          filters:
            - StripPrefix=1
   

ReadBodyPredicateFactory

在F版中不能通过配置使用,在H版及更高版本中可以通过配置使用,在该路由断言器中,会读取请求内容,缓存到内存中(ServerWebExchange的attributes,其中Key为:cachedRequestBodyObject)。可以通过判断体中的内容,实现更精细化的控制

XML 复制代码
[
  {
    "filters": [
     {
       "name": "StripPrefix",
        "args": {
           "_genkey_0": "1"
         }
      },
      {
        "name": "ModifyRequestBody",
        "args": {
          "inClass": "java.lang.String",
          "outClass": "java.lang.String",
          "rewriteFunction": "#{@testRewriteFunction}"
        }
      },
      {
        "name":"Retry",
         "args":{
            "retries": 3,
            "methods": ["GET", "POST"]
         }
      },
      {
          "name": "ModifyResponseBody",
          "args": {
            "inClass": "java.lang.String",
            "outClass": "java.lang.String",
            "rewriteFunction": "#{@testResponseBodyRewriteFunction}"
          }
       }
    ],
    "id": "test",
    "order": 0,
       "predicates": [
      {
        "args": {
          "pattern": "/sc-c/**"
        },
        "name": "Path"
      },
      {
        "name": "ReadBody",
        "args": {
            "inClass":"java.lang.String",
            "predicate":"#{@bodyPredicate}"
        }
      }
    ],
    "uri": "lb://sc-consumer"
  }
]

也可以在代码里面定义

java 复制代码
@Bean
    public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes().route("test11",r -> r.readBody(String.class,body -> {
                           try {
                               JSONObject entries = JSONUtil.parseObj(body);
                                                             return entries.containsKey("address");
                           } catch (Exception e) {
                               return false;
                           }
                        }).and().path("/sc-c/**")
                        .filters(f -> f.stripPrefix(1)
                                .modifyRequestBody(String.class,String.class,
                                        (exchange,s) -> Mono.just(s + "test"))
                                .retry((retryConfig -> {
                                    retryConfig.setRetries(3);
                                    retryConfig.setMethods(HttpMethod.POST,HttpMethod.GET);
                                    retryConfig.setExceptions(RuntimeException.class);
                                }))
                                .modifyResponseBody(String.class,String.class,(exchange,s) -> {
                                    try {
                                        JSONObject entries = JSONUtil.parseObj(s);
                                        entries.set("appName","yc-music");
                                        return Mono.just(JSONUtil.toJsonStr(entries));
                                             } catch (Exception e) {
                                        return Mono.just(s);
                                    }
                                }))
                        .uri("lb://sc-consumer"))
                .build();

    }
                                   
                           

WeightRoutePredicateFactory

用以指定路由的权重,可以在灰度发布,AB测试时使用,以下是配置使用示例

XML 复制代码
spring:
  application:
    name: sc-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
      routes:
        - id: sc-service
          uri: lb://sc-consumer
          predicates:
            - Path=/sc-c/**
            - Weight=group1,80
          filters:
            - StripPrefix=1

        - id: sc-service1
          uri: lb://sc-consumer1
          predicates:
            - Path=/sc-c/**
            - Weight=group1,20
          filters:
            - StripPrefix=1

在如上的配置中,sc-consumer1和sc-consumer是同一个服务的不同版本,按照如上的配置就可以实现控制流量的目的

相关推荐
水云桐程序员15 小时前
C++可以写手机应用吗
开发语言·c++·智能手机
测试员周周15 小时前
【AI测试智能体】为什么传统测试方法对智能体失效?
开发语言·人工智能·python·功能测试·测试工具·单元测试·测试用例
kyriewen15 小时前
百度用6%成本碾压硅谷?中国AI把性价比玩明白了
前端·百度·ai编程
kyriewen16 小时前
你还在手动敲命令部署?GitHub Actions 让你 push 即上线,摸鱼时间翻倍
前端·面试·github
RSTJ_162516 小时前
PYTHON+AI LLM DAY THREETY-NINE
开发语言·人工智能·python
想学习java初学者16 小时前
SpringBoot整合Vertx-Mqtt多租户(优化版)
java·spring boot·后端
AC赳赳老秦17 小时前
政企内网落地:OpenClaw 离线环境深度适配方案,无外网场景下本地化模型对接与全功能使用
java·大数据·运维·python·自动化·deepseek·openclaw
赏金术士17 小时前
Kotlin 从入门到进阶 之函数模块(核心基础)(二)
android·开发语言·kotlin
weixin_4491736517 小时前
在 Java 中,‌线程安全的 List‌ 主要有以下几种实现方式,它们的效率取决于具体的使用场景(尤其是读写比例):
java·线程安全的list
砚底藏山河17 小时前
股票数据API接口:如何获取股票历历史分时KDJ数据
java·python·maven