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