微服务网关Spring Cloud Gateway之Predicate
Spring Cloud Gateway
官方文档中对 Predicate
的定义如下:
This is a Java 8 Function Predicate.The input type is a Spring Framework ServerWebExchange.This lets you match on anything from the HTTP request,such as headers orparameters.
它属于 Java8
语言中的 Predicate
函数(Predicate
可以翻译为谓词、断言,不同的中文文档中叫法可能不同),参数为 ServerWebExchange
对象。可以让开发人员匹配任意的 HTTP
请求,不论是通过请求头还是请求参数。
简单理解,Spring Cloud Gateway
中的 Predicate
配置就是一个条件判断工具。开发人员在服务网关项目中配置之后,可以使用它来验证接收的请求,如果符合当前配置的规则,就通过验证,进而服务网关将该请求路由到微服务;如果不符合当前配置的规则,就无法通过验证,也不会将当前请求路由到微服务,而是返回错误信息。
在配置文件中,断言的配置项为 spring.cloud.gateway.routes.predicates
,可以配置一个断言,即满足一个条件后路由配置生效,也可以配置多个断言,需要同时满足多个条件,路由配置才会生效。比如,前文中的 Path
就是一个断言配置,Path=/goods/**
使用了内置的 PathRoutePredicateFactory
断言工厂,表示若访问网关项目的路径是以 /goods
开头的,路由配置就生效。
Spring Cloud Gateway内置断言工厂
Spring Cloud Gateway
中提供了很多的内置断言供开发人员直接使用,能够帮助开发人员实现不同的路由配置。
内置断言工厂列表及功能
内置的断言工厂类都实现了 AbstractRoutePredicateFactory
抽象类,在 3.1.1 版本中共有 14 个,内置断言工厂列表如图 9-10 所示。

常用的断言工厂介绍如下。
-
AfterRoutePredicateFactory
:设置时间参数,表示路由配置在指定时间点之后生效。配置格式如下:- After=2025-05-20T08:00:00.000+08:00[Asia/Shanghai]
-
BeforeRoutePredicateFactory
:设置时间参数,表示路由配置在指定时间点之前生效。配置格式如下:- Before=2035-05-20T08:00:00.000+08:00[Asia/Shanghai]
-
BetweenRoutePredicateFactory
:设置时间区间,表示路由配置在指定的时间区间内生效。配置格式如下:- Between=2025-05-20T08:00:00.000+08:00[Asia/Shanghai],2035-05-20T 08:00:00.000+08:00[Asia/Shanghai]
-
CookieRoutePredicateFactory
:设置Cookie
名称和Cookie
值的正则表达式,表示路由配置在匹配该Cookie
配置后生效。配置格式如下:- Cookie=myCookie; newbee*
-
HeaderRoutePredicateFactory
:设置请求Header
名称和Header
值的正则表达式,表示路由配置在匹配该请求Header
配置后生效。配置格式如下:- Header=token, newbee*
-
HostRoutePredicateFactory
:设置请求Host
,表示路由配置在请求的Host
符合条件后生效,多个Host
以逗号分开。配置格式如下:- Host=**.newbee.ltd,**.newbee.com
-
MethodRoutePredicateFactory
:设置请求方法,表示路由配置在请求方法符合条件后生效。配置格式如下:- Method=POST,GET
-
PathRoutePredicateFactory
:设置请求路径规则,表示路由配置在匹配该请求路径配置后生效,有多个规则以逗号分开。配置格式如下:- Path=/goods/*/*
-
QueryRoutePredicateFactory
:设置请求参数和参数值的正则表达式,表示路由配置在请求参数符合条件后生效。配置格式如下:- Query=goodsName, iPhone.
这些断言工厂的实现主要针对请求的时间信息及请求中的地址信息、参数信息设定特定的规则,以此来判断当前的路由规则是否生效。更多内容可以参考 Spring Cloud Gateway
的官方文档,见网址5。
使用内置断言工厂配置路由规则
Spring Cloud Gateway
的内置断言介绍完毕,接下来笔者使用内置的 MethodRoutePredicateFactory
和 QueryRoutePredicateFactory
编写一个示例演示它们的作用。本节代码是在 spring-cloud-alibaba-gateway-demo
项目的基础上修改的,具体步骤如下。
-
修改项目名称。
修改项目名称为
spring-cloud-alibaba-gateway-predicate-demo
,之后把各个模块中pom.xml
文件的artifactId
修改为spring-cloud-alibaba-gateway-predicate-demo
。 -
修改基本配置。
为了做章节区分,这里把
gateway-demo
和gateway-demo2
项目中的端口号分别修改为8137
和8139
,并且在gateway-demo
项目配置文件中添加注册中心的配置。修改
goods-service-demo
项目中goodsList
接口的请求方式为POST
,代码如下:@PostMapping("/goods/page/{pageNum}") public String goodsList(@PathVariable("pageNum") int pageNum) { // 返回信息给调用端 return "请求 goodsList,当前服务的端口号为" + applicationServerPort; }
-
设置路由规则。
除
Path
路径规则外,分别增加参数规则和请求方法的规则,代码如下:spring.cloud.gateway.routes[0].id=goods-service-route spring.cloud.gateway.routes[0].uri=lb://newbee-cloud-goods-service spring.cloud.gateway.routes[0].order=1 spring.cloud.gateway.routes[0].predicates[0]=Path=/goods #goodsId 参数必须为数字 spring.cloud.gateway.routes[0].predicates[1]=Query=goodsId,^\d+$ spring.cloud.gateway.routes[1].id=goods-service-route2 spring.cloud.gateway.routes[1].uri=lb://newbee-cloud-goods-service spring.cloud.gateway.routes[1].order=0 #路径以/goods/page/开头的请求,其请求方法必须是 POST 方式 spring.cloud.gateway.routes[1].predicates[0]=Path=/goods/page/** spring.cloud.gateway.routes[1].predicates[1]=Method=POST
上述断言配置分别表示当请求路径为 /goods
的接口时,必须包含 goodsId
参数,并且参数为数字;当请求路径以 /goods/page/
开头时,其请求方法必须是 POST
方式。
编码完成后进行功能验证,需要启动 Nacos Server
,之后依次启动 gateway-demo
和 goods-service-demo
项目。如果未能成功启动,则开发人员需要查看控制台中的日志是否报错,并及时确认问题和修复。启动成功后进入 Nacos
控制台,单击 “服务管理” 中的服务列表,可以看到列表中已经存在两个服务的服务信息。
依次使用不同的地址进行测试,结果见表 9-2。

还有其他内置断言工厂可供使用,因篇幅有限,就不再一一举例了,读者可以自行对照前文中介绍的内置断言工厂进行编码和测试。
自定义断言编码实践
Spring Cloud Gateway
提供了非常丰富和功能完善的断言工厂供开发人员使用。不过,除使用内置的断言工厂外,开发人员也可以根据具体的业务需求,自定义断言工厂并进行配置。
自定义断言工厂的编码并不复杂,前文中介绍的内置断言工厂都实现了 AbstractRoutePredicateFactory
抽象类,命名方式为 xxxRoutePredicateFactory
,在配置文件中写上 -xxx
即可。根据这几个固定的写法,可以自行实现一个断言工厂类。比如,只允许查询 goodsId
为 10000~100000
的商品数据,以下为具体的实现步骤。
-
编写
GoodsIdRoutePredicateFactory
类。在
gateway-demo2
项目中新建ltd.gateway.cloud.newbee.predicate
包,并新建GoodsIdRoutePredicateFactory.java
文件,具体代码及注释如下:package ltd.gateway.cloud.newbee.predicate; import java.util.Arrays; import java.util.List; import java.util.function.Predicate; import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory; import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate; import org.springframework.stereotype.Component; import org.springframework.validation.annotation.Validated; import org.springframework.web.server.ServerWebExchange; // 自定义路由断言工厂 处理 goodsId @Component public class GoodsIdRoutePredicateFactory extends AbstractRoutePredicateFactory<GoodsIdRoutePredicateFactory.Config> { public GoodsIdRoutePredicateFactory() { // 构造函数 super(Config.class); } @Override public List<String> shortcutFieldOrder() { // 定义配置文件中的参数项 (最大值和最小值) return Arrays.asList("minValue", "maxValue"); } @Override public Predicate<ServerWebExchange> apply(Config config) { return new GatewayPredicate() { @Override public boolean test(ServerWebExchange exchange) { // 获取 goodsId 参数的值 String goodsId = exchange.getRequest().getQueryParams().getFirst("goodsId"); if (null != goodsId) { int numberId = Integer.parseInt(goodsId); // 判断 goodsId 是否在配置区间内 if (numberId > config.getMinValue() && numberId < config.getMaxValue()) { // 符合条件,返回 true,路由规则生效 return true; } } // 不符合条件,返回 false,路由规则不生效 return false; } }; } @Validated // 接收配置文件中定义的最大值和最小值 public static class Config { private int minValue; private int maxValue; public int getMinValue() { return minValue; } public void setMinValue(int minValue) { this.minValue = minValue; } public int getMaxValue() { return maxValue; } public void setMaxValue(int maxValue) { this.maxValue = maxValue; } } }
该类代码分别定义了配置文件中定义的区间参数
minValue
和maxValue
。在test()
方法中是具体的判断逻辑,获取goodsId
参数值后判断是否在配置的区间内,若符合条件,就返回true
,路由规则生效;若不符合条件,就返回false
,路由规则不生效。 -
配置自定义断言工厂。
在
application.properties
配置文件中配置这个自定义的断言工厂。路由配置如下:spring.cloud.gateway.routes[0].id=goods-service-route spring.cloud.gateway.routes[0].uri=lb://newbee-cloud-goods-service spring.cloud.gateway.routes[0].order=1 spring.cloud.gateway.routes[0].predicates[0]=Path=/goods # 自定义断言配置,配置项为goodsId,最大值为100000,最小值为10000 spring.cloud.gateway.routes[0].predicates[1]=GoodsId=10000,100000
-
功能验证。
编码完成后,需要启动
Nacos Server
,之后依次启动gateway-demo2
和goods-service-demo
项目。如果未能成功启动,则开发人员需要查看控制台中的日志是否报错,并及时确认问题和修复。启动成功后进入Nacos
控制台,单击 “服务管理” 中的服务列表,可以看到列表中已经存在两个服务的服务信息。 -
打开浏览器进行功能验证,依次使用不同的地址进行测试,页面显示内容如图 9-11 所示。结果整理见表 9-3。


自定义断言工厂功能验证成功!
考虑到读者的知识储备不同,本书中项目的配置文件都是 .properties
格式的,这种方式最简单也最好理解。除这种写法外,还可以使用 YML
配置文件进行网关路由的配置。当然,也可以使用 Java
代码来声明路由,写法如下:
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder,
ThrottleGatewayFilterFactory throttle) {
return builder.routes()
.route(r -> r.host("**.abc.org").and().path("/image/png")
.uri("http://httpbin.org:80")
)
.route(r -> r.path("/image/webp")
.uri("http://httpbin.org:80")
)
.route(r -> r.order(-1)
.host("**.throttle.org").and().path("/get")
.uri("http://httpbin.org:80")
)
.build();
}
读者可根据实际需要来完成服务网关项目的配置,虽然三种写法有些区别,但是其底层知识点是一模一样的。