在上一篇二十五、springCloudAlibaba-gateway的内置路由断言工厂 我们介绍了内置的路由断言工厂,这里我们来实时自定义断言工厂
1、实现思路
我们在IDEA中连按两下Shift键搜索QueryRoute就可以看到Query断言工厂怎么实现的,我们拷贝一份参考实现即可。
2、实现步骤
- 1、由于是约定大于配置,所以我们的类结尾应该是RoutePredicateFactory结尾,比如这里我自定义的断言类是MyCustomizeRoutePredicateFactory
- 2、必须继承AbstractRoutePredicateFactory
- 3、必须声明内部静态类,用来接收配置中的属性
- 4、需要结合shortcutFieldOrder进行属性绑定
- 5、通过apply进行逻辑判断,true为匹配成功,false为匹配失败
- 6、必须为bean
3和4其实就是接收配置中的green位置和hel.位置的属性值
predicates:
- Query=green,hel.
3、代码如下
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.suibibk.springCloud.gateway;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.function.Predicate;
import javax.validation.constraints.NotEmpty;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.cloud.gateway.handler.predicate.GatewayPredicate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.server.ServerWebExchange;
@Component
public class MyCustomizeRoutePredicateFactory extends AbstractRoutePredicateFactory<MyCustomizeRoutePredicateFactory.Config> {
public static final String PARAM_KEY = "param";
public static final String REGEXP_KEY = "regexp";
public MyCustomizeRoutePredicateFactory() {
super(Config.class);
}
public List<String> shortcutFieldOrder() {
return Arrays.asList("param", "regexp");
}
public Predicate<ServerWebExchange> apply(final Config config) {
return new GatewayPredicate() {
public boolean test(ServerWebExchange exchange) {
//如果参数中有我们配置的参数
if(exchange.getRequest().getQueryParams().containsKey(config.getParam())){
return true;
}else{
return false;
}
}
};
}
@Validated
public static class Config {
private @NotEmpty String param;
private String regexp;
public Config() {
}
public String getParam() {
return this.param;
}
public Config setParam(String param) {
this.param = param;
return this;
}
public String getRegexp() {
return this.regexp;
}
public Config setRegexp(String regexp) {
this.regexp = regexp;
return this;
}
}
}
逻辑很简单,只要参数中有我在断言里面配置的key就通过
gateway:
#路由规则
routes:
- id: order_route # 路由的唯一标识
uri: lb://order-service #需要转发的地址.lb本地负载均衡策略
#断言规则 用于路由规则的匹配
predicates:
- Path=/order-service/**
#- Query=green,hel.
- MyCustomize=test
#- After=2023-11-13T21:05:39.811+08:00[Asia/Shanghai]
#匹配请求http://localhost:8088/order-service/order/add
#过滤器 用于过滤请求
filters:
- StripPrefix=1 #转发之前去掉第一层路径
#http://localhost:8010/order/add
#- id: stock_route
我们测试http://localhost:8088/order-service/order/add?test=helo 正常返回,但是去掉test或则改为test1就报404了。
4、总结
参考,拷贝,修改来实现!