我正在尝试将大量路由配置转换为Spring Cloud Gateway Yaml DSL。
我遇到的一个问题是(非常常见的情况)多条路径应映射到同一条路线。也就是说,任何匹配/abc/**
,/def/**
或/ghi/**
的传入URL应该被路由到一些uri http://example.org
(并应用相同的过滤器集等)。
在基于Fluent的Java路由方法中,可以通过.or().
方法来实现,例如:r.path("/abc/**").or().path("/def/**").or().path("/fhi/**")...
如何通过基于YAML的路由配置实现相同的功能?
“多个路由谓词工厂可以组合并且可以组合 通过逻辑
and
“
是否有另一种方法可以通过Yaml来实现路径谓词的OR-ing,而无需声明多个路由?可以重写某些东西来支持这一点吗?
答案 0 :(得分:1)
您可能已经找到答案了。但为了记录,我可以说可以为谓词添加多个路径,如下所示:
spring:
cloud:
gateway:
routes:
- id: instructors_route
uri: lb://INSTRUCTOR-SERVICE/
predicates:
- Path=/api/v1/instructors**,/api/v1/countries**
答案 1 :(得分:0)
我发现了处理谓词组合的方法:
RouteDefinitionRouteLocator.java: combinePredicates
:
private AsyncPredicate<ServerWebExchange> combinePredicates(RouteDefinition routeDefinition) {
List<PredicateDefinition> predicates = routeDefinition.getPredicates();
AsyncPredicate<ServerWebExchange> predicate = lookup(routeDefinition, predicates.get(0));
for (PredicateDefinition andPredicate : predicates.subList(1, predicates.size())) {
AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate);
predicate = predicate.and(found);
}
return predicate;
}
由于它是私有方法,为了用执行Path
谓词的逻辑析取(“ OR-ing”)的谓词组合逻辑覆盖此逻辑,扩展了{{1} }必须重新定义所有导致最终调用RouteDefinitionRouteLocator
的方法(这不是采用最灵活的路由)。但是,通过重新实现如下方法,我能够实现所需的功能:
combinePredicates
然后,使用这个新类覆盖private AsyncPredicate<ServerWebExchange> combinePredicates(RouteDefinition routeDefinition) {
//filter out "Path" predicates and place in separate list
List<PredicateDefinition> predicates = routeDefinition.getPredicates();
List<PredicateDefinition> pathPredicates = new ArrayList();
for(PredicateDefinition predicate : predicates){
if (PATH_PREDICATE_NAME.equals(predicate.getName())) {
pathPredicates.add(predicate);
}
}
predicates.removeAll(pathPredicates);
//create an uber predicate out of the "Path" predicates by combining them w/ `or`
AsyncPredicate<ServerWebExchange> pathPredicate = null;
if(pathPredicates.size()>0){
pathPredicate = lookup(routeDefinition, pathPredicates.get(0));
for (PredicateDefinition andPredicate : pathPredicates.subList(1, pathPredicates.size())) {
AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate);
pathPredicate = pathPredicate.or(found);
}
}
//"AND" together the uber path predicate and the rest of the predicates for the route
AsyncPredicate<ServerWebExchange> predicate;
List<PredicateDefinition> predicateSubList;
if(pathPredicate != null) {
predicate = pathPredicate;
predicateSubList = predicates;
} else {
predicate = lookup(routeDefinition, predicates.get(0));
predicateSubList = predicates.subList(1, predicates.size());
}
for (PredicateDefinition andPredicate : predicateSubList) {
AsyncPredicate<ServerWebExchange> found = lookup(routeDefinition, andPredicate);
predicate = predicate.and(found);
}
return predicate;
}
中声明的routeDefinitionRouteLocator
RouteLocator
@Bean
配置,可以使用新逻辑。