Spring Cloud Gateway将路由匹配作为最基本的功能。而这个功能是通过路由断言工厂完成的。Spring Cloud Gateway中包含了很多种内置的路由断言工厂。所有这些断言都可以匹配HTTP请求的不同属性,并且可以根据逻辑与状态,将多个路由断言工厂复合使用。
一、After路由断言工厂
After路由断言接受一个参数,一个日期时间(它是一个javaZonedDateTime)。此断言会将请求访问到Gateway的时间与此断言指定的日期时间进行对比,如果请求访问时间是在指定参数之后,则匹配成功,断言为 true。
1.1 配置式路由方式
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2023-08-12T16:21:07.789-07:00
此断言只满足访问到GateWay的时间在2023年8月12日16:21:07时间之后的任何请求。
在浏览器地址栏输入本机ip:配置端口号。如果满足断言,则跳转到https://example.org页面。如果不满足断言要求,则访问时出现404错误码。
1.2 API式路由方式
@Configuration
public class GatewayConfig {
/**
* After路由断言工厂 —— API式
* @param builder
* @return
*/
@Bean
public RouteLocator afterRouteLocator(RouteLocatorBuilder builder) {
// 当前时间减3天,并且将系统默认时区设置为当前时区
ZonedDateTime dateTime = LocalDateTime.now().minusDays(3).atZone(ZoneId.systemDefault());
return builder.routes()
.route("after_route", predicateSpec -> predicateSpec.after(dateTime)
.uri("https://example.org"))
.build();
}
}
二、Before路由断言工厂
After路由断言接受一个参数,一个日期时间(它是一个javaZonedDateTime)。此断言会将请求访问到Gateway的时间与此断言指定的日期时间进行对比,如果请求访问时间是在指定参数之前,则匹配成功,断言为 true。
2.1 配置式路由方式
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2025-01-20T16:21:07.789-07:00
此断言只满足访问到GateWay的时间在2025年1月20日16:21:07时间之前的任何请求。
在浏览器地址栏输入本机ip:配置端口号。如果满足断言,则跳转到https://example.org页面。如果不满足断言要求,则访问时出现404错误码。
2.2 API式路由方式
@Configuration
public class GatewayConfig {
/**
* Before路由断言工厂 —— API式
* @param builder
* @return
*/
@Bean
public RouteLocator beforeRouteLocator(RouteLocatorBuilder builder) {
// 当前时间减3天,并且将系统默认时区设置为当前时区
ZonedDateTime dateTime = LocalDateTime.now().minusDays(3).atZone(ZoneId.systemDefault());
return builder.routes()
.route("before_route", predicateSpec -> predicateSpec.before(dateTime)
.uri("https://example.org"))
.build();
}
}
三、Between路由断言工厂
After路由断言接受两个参数,两个日期时间datetime1和datetime2(它们都是javaZonedDateTime对象)。此断言会将请求访问到Gateway的时间与此断言指定的datetime1和datetime2日期时间进行对比,如果请求访问时间是在datetime1指定参数之前,且在datetime2指定参数之后,则匹配成功,断言为 true。
3.1 配置式路由方式
spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2018-09-20T16:21:07.789-07:00, 2025-01-21T16:21:07.789-07:00
此断言只满足访问到GateWay的时间在2018年9月20日16:21:07之后,且在2025年1月20日16:21:07时间之前的任何请求。
在浏览器地址栏输入本机ip:配置端口号。如果满足断言,则跳转到https://example.org页面。如果不满足断言要求,则访问时出现404错误码。
3.2 API式路由方式
@Configuration
public class GatewayConfig {
/**
* Between路由断言工厂 —— API式
* @param builder
* @return
*/
@Bean
public RouteLocator betweenRouteLocator(RouteLocatorBuilder builder) {
// 当前时间减3天,并且将系统默认时区设置为当前时区
ZonedDateTime dateTimeBegin = LocalDateTime.now().minusDays(3).atZone(ZoneId.systemDefault());
// 当前时间加5天,并且将系统默认时区设置为当前时
ZonedDateTime dateTimeAfter = LocalDateTime.now().plusDays(5).atZone(ZoneId.systemDefault());
return builder.routes()
.route("between_route", predicateSpec -> predicateSpec.between(dateTimeBegin, dateTimeAfter)
.uri("https://example.org"))
.build();
}
}
四、Cookie路由断言工厂
Cookie路由断言接受两个参数,即Cookie的key和value(value是一个Java正则表达式)。此断言会与访问到Gateway的请求中携带的Cookie进行对比,如果请求的Cookie携带了指定的key和value,则匹配成功,断言为 true。
4.1 配置式路由方式
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
4.2 API式路由方式
@Configuration
public class GatewayConfig {
/**
* Cookie路由断言工厂 —— API式
* @param builder
* @return
*/
@Bean
public RouteLocator cookieRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("cookie_route", predicateSpec -> predicateSpec.cookie("city", "siping")
.uri("https://example.org"))
.build();
}
}
五、Header路由断言工厂
Header路由断言接受两个参数,即请求头Header的key和value(value是一个Java正则表达式)。此断言会与访问到Gateway的请求中携带的Header进行对比,如果请求的Header携带了指定的key和value,则匹配成功,断言为true。
5.1 配置式路由方式
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
使用Postman进行测试,在请求头中添加满足断言的Header,则可以成功访问到页面。但如果没有设置Header或设置Header的key和value不满足指定的断言,则无法访问到。
5.2 API式路由方式
@Configuration
public class GatewayConfig {
/**
* Header路由断言工厂 —— API式
* @param builder
* @return
*/
@Bean
public RouteLocator headerRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("header_route", predicateSpec -> predicateSpec.header("X-Request-Id", "\\d+")
.and()
.header("Color", "re.+")
.uri("https://example.org"))
.build();
}
}
六、Host路由断言工厂
Host路由断言接受一个参数,即主机名模式列表(请求头中的Host属性)。当请求中携带了指定的Host属性值时,则匹配成功,断言为true。
6.1 配置式路由方式
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org, **.anotherhost.org
6.2 API式路由方式
@Configuration
public class GatewayConfig {
/**
* Host路由断言工厂 —— API式
* @param builder
* @return
*/
@Bean
public RouteLocator hostRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("host_route", predicateSpec -> predicateSpec
.host(**.somehost.org, **.anotherhost.org)
.uri("https://example.org"))
.build();
}
}
七、Method路由断言工厂
Method路由断言接受一个参数,该参数可以是一个参数,也可以是多个参数,这个参数指定的是请求方法(POST、GET、PUT、DELETE)。当请求中使用了指定的请求方法时,则匹配成功,断言为true。
7.1 配置式路由方式
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET, POST
此断言只满足访问到GateWay的请求方法为GET或POST的任何请求。
7.2 API式路由方式
@Configuration
public class GatewayConfig {
/**
* Method路由断言工厂 —— API式
* @param builder
* @return
*/
@Bean
public RouteLocator methodRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("method_route", predicateSpec -> predicateSpec
.method("GET", "POST")
.uri("https://example.org"))
.build();
}
}
八、Path路由断言工厂
Method路由断言接受两个参数,第一个参数为Spring PathMatcher模式列表,即URI;第二个参数是一个名为matchTrailingFlash的可选标志(默认为true)。当请求路径中包含指定的URI时,则匹配成功,断言为true。并且会将该匹配上的URI拼接到要转向的目标URI的后面,形成一个统一的URI。
8.1 配置式路由方式
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
8.2 API式路由方式
@Configuration
public class GatewayConfig {
/**
* Between路由断言工厂 —— API式
* @param builder
* @return
*/
@Bean
public RouteLocator betweenRouteLocator(RouteLocatorBuilder builder) {
// 当前时间减3天,并且将系统默认时区设置为当前时区
ZonedDateTime dateTimeBegin = LocalDateTime.now().minusDays(3).atZone(ZoneId.systemDefault());
// 当前时间加5天,并且将系统默认时区设置为当前时
ZonedDateTime dateTimeAfter = LocalDateTime.now().plusDays(5).atZone(ZoneId.systemDefault());
return builder.routes()
.route("between_route", predicateSpec -> predicateSpec.between(dateTimeBegin, dateTimeAfter)
.uri("https://example.org"))
.build();
}
}https://example.org
九、Query路由断言工厂
Query路由断言工厂接受两个参数,一个必需的请求参数param和一个可选的regexp(它是Java正则表达式)。当请求中包含了指定的参数名,或名值对时,匹配成功,断言为True。
9.1 配置式路由方式
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
9.2 API式路由方式
@Configuration
public class GatewayConfig {
/**
* Query路由断言工厂 —— API式
* @param builder
* @return
*/
@Bean
public RouteLocator queryRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("query_route", predicateSpec -> predicateSpec
.query("color", "gr.+")
.and()
.query("size")
.uri("https://example.org"))
.build();
}
}
十、RemoteAddr路由断言工厂
RemoteAddr路由断言工厂,用于判断提交请求的客户端ip地址是否在断言中指定的ip范围或ip列表中。若请求的客户端ip在指定的ip范围或ip列表中,则匹配成功,断言为True。例如192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码)。
10.1 配置式路由方式
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.3.1/24
此断言只满足访问到GateWay的主机ip属于192.168.3网段的任何请求。
10.2 API式路由方式
@Configuration
public class GatewayConfig {
/**
* RemoteAddr路由断言工厂 —— API式
* @param builder
* @return
*/
@Bean
public RouteLocator remoteAddrRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("remoteAddr_route", predicateSpec -> predicateSpec
.remoteAddr("192.168.3.1/24")
.uri("https://example.org"))
.build();
}
}
十一、Weight路由断言工厂
Weight路由断言工厂接受两个参数,一个是组group;另一个是权重Weight(一个int)。该断言用于实现对同一组中的不同URI实现指定权重的负载均衡,对于同一组中的多个URI地址,路由器会根据设置的权重,按比例将请求转发给相应的URI。
11.1 配置式路由方式
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
11.2 API式路由方式
@Configuration
public class GatewayConfig {
/**
* Weight路由断言工厂 —— API式
* @param builder
* @return
*/
@Bean
public RouteLocator weightRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("weight_high", predicateSpec -> predicateSpec
.weight(group1, 8)
.uri("https://weighthigh.org"))
.route("weight_low", predicateSpec -> predicateSpec
.weight(group2, 2)
.uri("https://weightlow.org"))
.build();
}
}
十二、XForwarded Remote Addr路由断言工厂
XForwarded Remote Addr路由断言工厂接受一个参数,是一个ip地址,例如192.168.0.1/16(其中192.168.0.1是IP地址,16是子网掩码)。只要当前请求头中追加入X-Forwarded-For的ip出现在路由指定的ip列表中,则匹配成功,断言为 true。
12.1 配置式路由方式
spring:
cloud:
gateway:
routes:
- id: xforwarded_remoteaddr_route
uri: https://example.org
predicates:
- XForwardedRemoteAddr=192.168.1.1/24, 192.168.60.10
12.2 API式路由方式
@Configuration
public class GatewayConfig {
/**
* XForwardedRemoteAddr路由断言工厂 —— API式
* @param builder
* @return
*/
@Bean
public RouteLocator xForwardedRemoteAddrRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("xForwardedRemoteAddr_route", predicateSpec -> predicateSpec
.xForwardedRemoteAddr("192.168.1.1/24", "192.168.60.10")
.uri("https://example.org"))
.build();
}
}