Spring 云网关 2.0 转发路径变量

Spring Cloud Gateway 2.0 forward path variable

如何在Spring云网关2.0中转发路径变量?

如果我们有一个具有 2 个端点的微服务:/users/users/{id} 并且在端口 8080 上 运行,如何将请求转发到具有 id 路径变量的端点?

以下网关配置成功转发到/users端点,但第二条路由将请求转发到真实服务的同一个/users端点。

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("users", t -> t.path("/users").uri("http://localhost:8080/users"))
        .route("userById", t -> t.path("/users/**").uri("http://localhost:8080/users/"))
        .build();
}

我正在使用来自 spring 云 Finchley.BUILD-SNAPSHOT

spring-cloud-starter-gateway

必须使用 rewritePath 过滤器:

@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
        return builder.routes()
            .route("users", t -> t.path("/users")
                .uri("http://localhost:8080/users"))
            .route("userById", t -> t.path("/users/**")
                .filters(rw -> rw.rewritePath("/users/(?<segment>.*)", "/users/${segment}"))
                .uri("http://localhost:8080/users/"))
        .build();
    }

YAML 版本在 documentation:

中指定
spring:
  cloud:
    gateway:
      routes:
      - id: rewritepath_route
        uri: http://example.org
        predicates:
        - Path=/foo/**
        filters:
        - RewritePath=/foo/(?<segment>.*), /$\{segment}

经过一些研究,请在下面找到对我有用的方法。两种方法产生相同的结果。

这是我的设置:

  • 网关是 运行 http://localhost:8090
  • 名为 /context 的基本路径用作网关的入口点
  • http://localhost:8091/my-resources 上调用了 my-resources 运行 的服务。当不带参数调用 /my-resources 时,它 returns 所有资源。当使用参数调用时,它 returns 具有相应 RID(如果有)
  • 的资源

网关被配置为所有传输到 http://localhost:8090/context/my-resources/ 的路径变量(可能 none)被转发到 uri http://localhost:8091/my-resources/

方法一:使用application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: route_id
        predicates:
        - Path=/context/my-resources/**
        filters:
        - RewritePath=/context/my-resources/(?<RID>.*), /my-resources/$\{RID}
        uri: http://localhost:8091

方法二:使用Java类似配置

@Bean
public RouteLocator routes(RouteLocatorBuilder routeBuilder) {
    return routeBuilder.routes()
            .route("route_id",
                    route -> route
                            .path("/context/my-resources/**")
                            .filters(f -> f.rewritePath("/context/my-resources/(?<RID>.*)", "/my-resources/${RID}"))
                            .uri("http://localhost:8091")
            )
            .build();
}