繁体   English   中英

从Zuul迁移到Spring Cloud Gateway时,如何“先删除gobal前缀('/ api')然后转到lb://”

[英]How to “remove the gobal prefix('/api') then goto the lb:// ” when migrate to spring cloud gateway from zuul

我想从zuul迁移到Spring Cloud Gateway,我不想更改以前应用程序的配置。 我想知道如何处理带有“ / api / +'serviceId'”的网址,路由到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 ,没有

您可以自定义通过属性使用的自动过滤器和谓词。

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.patternargs.regexp )都是Spring表达式语言(SpEL)表达式,因此单引号和+等。

如果不同的路由需要具有不同的前缀,则需要在属性中定义每个路由。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM