从 zuul 迁移到 spring 云网关时如何 "remove the gobal prefix('/api') then goto the lb:// "
How to "remove the gobal prefix('/api') then goto the lb:// " when migrate to spring cloud gateway from zuul
我想从 zuul 迁移到 spring 云网关,我不想更改以前应用程序的配置。我想知道如何使用“/api/ + 'serviceId'”处理 url,路由到 lb://serviceId
之前的zuul配置
zuul:
prefix: /api
eureka 有很多服务注册,我不想为每个注册一个路由。
例如。 org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator
自动生成的路线
{
"route_id": "CompositeDiscoveryClient_APIGATEWAY",
"route_definition": {
"id": "CompositeDiscoveryClient_APIGATEWAY",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/apigateway/**"
}
}
],
"filters": [
{
"name": "RewritePath",
"args": {
"regexp": "/apigateway/(?<remaining>.*)",
"replacement": "/${remaining}"
}
}
],
"uri": "lb://APIGATEWAY",
"order": 0
}
我想要的是
{
"route_id": "CompositeDiscoveryClient_APIGATEWAY",
"route_definition": {
"id": "CompositeDiscoveryClient_APIGATEWAY",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/api/apigateway/**"
}
}
],
"filters": [
{
"name": "RewritePath",
"args": {
"regexp": "/api/apigateway/(?<remaining>.*)",
"replacement": "/${remaining}"
}
}
],
"uri": "lb://APIGATEWAY",
"order": 0
}
我如何配置我的路线以获得我想要的
而且我还找到了源码
public static List<PredicateDefinition> initPredicates() {
ArrayList<PredicateDefinition> definitions = new ArrayList<>();
// TODO: add a predicate that matches the url at /serviceId?
// add a predicate that matches the url at /serviceId/**
PredicateDefinition predicate = new PredicateDefinition();
predicate.setName(normalizeRoutePredicateName(PathRoutePredicateFactory.class));
predicate.addArg(PATTERN_KEY, "'/'+serviceId+'/**'");
definitions.add(predicate);
return definitions;
}
“'/'+serviceId+'/**'”没有前缀
[2019-01-10]更新
我认为@spencergibb 的建议是一个很好的解决方案,但我在 (SpEL) 方面遇到了新的麻烦
我尝试了很多方法:
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: '/${remaining}'
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
启动失败
Origin: class path resource [application.properties]:23:70
Reason: Could not resolve placeholder 'remaining' in value "'${remaining}'"
当我使用像
这样的转义符“\”时
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: '/$\{remaining}'
它开始成功但我在 运行
时遇到异常
org.springframework.expression.spel.SpelParseException: Expression [/$\{remaining}] @2: EL1065E: unexpected escape character.
at org.springframework.expression.spel.standard.Tokenizer.raiseParseException(Tokenizer.java:590) ~[spring-expression-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.expression.spel.standard.Tokenizer.process(Tokenizer.java:265) ~[spring-expression-5.0.5.RELEASE.jar:5.0.5.RELEASE]
更新 2
我在org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory
中找到了一个替换来处理“\”
...
@Override
public GatewayFilter apply(Config config) {
String replacement = config.replacement.replace("$\", "$");
return (exchange, chain) -> {
...
当谈到 SpelParseException
时,有 none
您可以自定义通过属性使用的自动过滤器和谓词。
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
predicates:
- name: Path
args:
pattern: "'/api/'+serviceId.toLowerCase()+'/**'"
filters:
- name: RewritePath
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
注意值(即 args.pattern
或 args.regexp
)都是 Spring 表达式语言 (SpEL) 表达式,因此单引号和 +
等...
如果不同的路由需要有不同的前缀,您需要在属性中定义每个路由。
我想从 zuul 迁移到 spring 云网关,我不想更改以前应用程序的配置。我想知道如何使用“/api/ + 'serviceId'”处理 url,路由到 lb://serviceId
之前的zuul配置
zuul:
prefix: /api
eureka 有很多服务注册,我不想为每个注册一个路由。
例如。 org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator
自动生成的路线{
"route_id": "CompositeDiscoveryClient_APIGATEWAY",
"route_definition": {
"id": "CompositeDiscoveryClient_APIGATEWAY",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/apigateway/**"
}
}
],
"filters": [
{
"name": "RewritePath",
"args": {
"regexp": "/apigateway/(?<remaining>.*)",
"replacement": "/${remaining}"
}
}
],
"uri": "lb://APIGATEWAY",
"order": 0
}
我想要的是
{
"route_id": "CompositeDiscoveryClient_APIGATEWAY",
"route_definition": {
"id": "CompositeDiscoveryClient_APIGATEWAY",
"predicates": [
{
"name": "Path",
"args": {
"pattern": "/api/apigateway/**"
}
}
],
"filters": [
{
"name": "RewritePath",
"args": {
"regexp": "/api/apigateway/(?<remaining>.*)",
"replacement": "/${remaining}"
}
}
],
"uri": "lb://APIGATEWAY",
"order": 0
}
我如何配置我的路线以获得我想要的
而且我还找到了源码
public static List<PredicateDefinition> initPredicates() {
ArrayList<PredicateDefinition> definitions = new ArrayList<>();
// TODO: add a predicate that matches the url at /serviceId?
// add a predicate that matches the url at /serviceId/**
PredicateDefinition predicate = new PredicateDefinition();
predicate.setName(normalizeRoutePredicateName(PathRoutePredicateFactory.class));
predicate.addArg(PATTERN_KEY, "'/'+serviceId+'/**'");
definitions.add(predicate);
return definitions;
}
“'/'+serviceId+'/**'”没有前缀
[2019-01-10]更新 我认为@spencergibb 的建议是一个很好的解决方案,但我在 (SpEL) 方面遇到了新的麻烦 我尝试了很多方法:
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: '/${remaining}'
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
启动失败
Origin: class path resource [application.properties]:23:70
Reason: Could not resolve placeholder 'remaining' in value "'${remaining}'"
当我使用像
这样的转义符“\”时args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: '/$\{remaining}'
它开始成功但我在 运行
时遇到异常org.springframework.expression.spel.SpelParseException: Expression [/$\{remaining}] @2: EL1065E: unexpected escape character.
at org.springframework.expression.spel.standard.Tokenizer.raiseParseException(Tokenizer.java:590) ~[spring-expression-5.0.5.RELEASE.jar:5.0.5.RELEASE]
at org.springframework.expression.spel.standard.Tokenizer.process(Tokenizer.java:265) ~[spring-expression-5.0.5.RELEASE.jar:5.0.5.RELEASE]
更新 2
我在org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory
中找到了一个替换来处理“\”
...
@Override
public GatewayFilter apply(Config config) {
String replacement = config.replacement.replace("$\", "$");
return (exchange, chain) -> {
...
当谈到 SpelParseException
时,有 none
您可以自定义通过属性使用的自动过滤器和谓词。
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
predicates:
- name: Path
args:
pattern: "'/api/'+serviceId.toLowerCase()+'/**'"
filters:
- name: RewritePath
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
注意值(即 args.pattern
或 args.regexp
)都是 Spring 表达式语言 (SpEL) 表达式,因此单引号和 +
等...
如果不同的路由需要有不同的前缀,您需要在属性中定义每个路由。