12.gateway中的断言(predicate)的使用:内置断言介绍、自定义断言
程序员文章站
2022-03-04 23:02:22
...
文章目录
Predicate(断言, 谓词) 用于进行条件判断,只有断言都返回真,才会真正的执行路由。
断言就是说: 在 什么条件下 才能进行路由转发
内置断言工厂
SpringCloud Gateway包括许多内置的断言工厂,所有这些断言都与HTTP请求的不同属性匹配体如下: 都是使用在 predicates:
下的
1.基于Datetime类型的断言工厂
此类型的断言根据时间做判断,主要有三个:
- AfterRoutePredicateFactory: 接收一个日期参数,判断请求日期是否晚于指定日期
- BeforeRoutePredicateFactory: 接收一个日期参数,判断请求日期是否早于指定日期
- BetweenRoutePredicateFactory: 接收两个日期参数,判断请求日期是否在指定时间段内
使用方式:
spring:
cloud:
gateway:
routes:
- id: shop-product # 路由的唯一标识
uri: lb://shop-product # 如果断言成功,将要转发去的地址
order: 0 # 优先级,越小优先级越高
predicates: # 断言,满足所有断言,才会进行转发
# 在这个时间之后才能进行访问
- After=2019-12-31T23:59:59.789+08:00[Asia/Shanghai]
2. 基于远程地址的断言工厂
- RemoteAddrRoutePredicateFactory: 接收一个IP地址段,判断请求主机地址是否在地址段中
- RemoteAddr=192.168.1.1/24
3. 基于Cookie的断言工厂
- CookieRoutePredicateFactory:接收两个参数,cookie 名字和一个正则表达式。 判断请求cookie是否具有给定名称且值与正则表达式匹配。
- Cookie=chocolate, ch.
4. 基于Header的断言工厂
- HeaderRoutePredicateFactory:接收两个参数,标题名称和正则表达式。 判断请求Header是否具有给定名称且值与正则表达式匹配。
- Header=X-Request-Id, \d+
5.基于Host的断言工厂
- HostRoutePredicateFactory:接收一个参数,主机名模式。判断请求的Host是否满足匹配规则。
- Host=**.testhost.org
6.基于Method请求方法的断言工厂
- MethodRoutePredicateFactory:接收一个参数,判断请求类型是否跟指定的类型匹配。
- Method=GET
7.基于Path请求路径的断言工厂
- PathRoutePredicateFactory:接收一个参数,判断请求的URI部分是否满足路径规则。
- Path=/foo/{segment}
8.基于Query请求参数的断言工厂
- QueryRoutePredicateFactory :接收两个参数,请求param和正则表达式, 判断请求参数是否具有给定名称且值与正则表达式匹配。
- Query=baz, ba.
9.基于路由权重的断言工厂
- WeightRoutePredicateFactory:接收一个 [组名,权重] 然后对于同一个组内的路由按照权重转发
gateway:
routes:
- id: weight_route1
uri: host1
predicates:
- Path=/product/**
- Weight=group3, 1
- id: weight_route2
uri: host2
predicates:
# 路径一致,组一致,权重不同
- Path=/product/**
- Weight= group3, 9
自定义路由断言工厂
我们来设定一个场景: 假设我们的应用仅仅让age在(min,max)之间的人来访问。
使用例子来体验一把自定义路由断言工厂
1.定义一个断言工厂,实现断言方法
新建一个类,继承 AbstractRoutePredicateFactory
类,这个类的泛型是 自定义断言工厂的一个内部类叫做Config
是一个固定的名字,在Config
类中定义自定义断言需要的一些属性,并且自定义断言工厂使用 @Component
注解,交给spring容器创建
这里的age是通过请求参数(request.getQueryParams())获取的,这个可以根据需要进行调整。你需要从请求头获取,就通过request.getHeaders() 获取即可。
@Component
public class AgeRoutePredicateFactory extends AbstractRoutePredicateFactory<AgeRoutePredicateFactory.Config> {
public AgeRoutePredicateFactory() {
super(AgeRoutePredicateFactory.Config.class);
}
//读取配置文件中的内容并配置给配置类中的属性
@Override
public List<String> shortcutFieldOrder() {
return Arrays.asList("minAge","maxAge");
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
// 获取请求参数中的 age 属性
String age = exchange.getRequest().getQueryParams().getFirst("age");
if(StringUtils.isNotEmpty(age)) {
try {
int a = Integer.parseInt(age);
boolean res = a >= config.minAge && a <= config.maxAge;
return res;
} catch (Exception e) {
System.out.println("输入的参数不是数字格式");
}
}
return false;
};
}
@Validated
public static class Config {
private Integer minAge;
private Integer maxAge;
public Integer getMinAge() {
return minAge;
}
public void setMinAge(Integer minAge) {
this.minAge = minAge;
}
public Integer getMaxage() {
return maxAge;
}
public void setMaxage(Integer maxage) {
this.maxAge = maxage;
}
}
}
在这个自定义断言中,.Config
中有两个属性 minAge 和 maxAge
在 apply()
方法中编写断言的比较逻辑
2. 在yml中使用自定义断言
在yml文件中使用自定义断言。
spring:
cloud:
gateway:
routes:
- id: shop-product # 路由的唯一标识
uri: lb://shop-product # 如果断言成功,将要转发去的地址
order: 0 # 优先级,越小优先级越高
predicates: # 断言,满足所有断言,才会进行转发
- Path=/product/** # 注意:这是使用= 不是:
# 自定义断言,第一个参数对应minAge,第二个参数对应maxAge
- Age=18, 60
从这里的演示应该可以看出来,自定义断言与系统自带断言的配置,在yml中只需要使用首部名称,默认忽略类名中的 RoutePredicateFactory
例如自定义的断言 AgeRoutePredicateFactory 在使用的时候,就是通过 -Age 进行指定的。
效果:
ok,就是这样