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是同一个服务的不同版本,按照如上的配置就可以实现控制流量的目的

相关推荐
微学AI3 小时前
一根针指向所有方向:挂谷猜想对 LLM Agent 技能-记忆架构的启示
开发语言·人工智能·架构·挂谷猜想
城管不管3 小时前
ReAct、Plan-and-Execute、Reflection 三大智能 Agent 范式核心区别
java·人工智能·算法·spring·ai·动态规划
郭老二4 小时前
【前端】vue3:编译步骤
前端
IT小白杨4 小时前
从环境制备到自动化工作流:多账号运营的工程化架构拆解
java·经验分享·自动化·安全架构·指纹浏览器
豆瓣鸡4 小时前
算法日记 - Day3
java·开发语言·算法
萧瑟余晖4 小时前
Java深入解析篇九之NIO详解
java·网络·nio
不在逃避q4 小时前
Trae/Vs Code/Cursor命令行无法跑npm命令
前端·arcgis·npm
夏殇之殁5 小时前
包中创建自定义列表项。 . 使用自定义列表项进行数据绑定 . 将天气预报数据保存到本地内存表,通过LiveBindings进行显示。 ...
服务器·前端·javascript
韭菜炒鸡肝天5 小时前
VTK开发笔记(一):VTK介绍,Qt..+VSx+VTK.编译
开发语言·笔记·qt
The Chosen One9855 小时前
高进度算法模板速记(待完善)
java·前端·算法