Spring 云网关 - Proxy/Forward URL 的整个子部分
Spring Cloud Gateway - Proxy/Forward the entire sub part of URL
我正在使用 Spring Cloud Gateway 2.0.0.M6 测试一个简单的网关。我只想将一个 URL 转发给另一个 URL 使用 ** regex
示例 1:/integration/sbl/foo/bar => localhost:4178/a-integration/sbl/foo/bar
示例 2:/integration/sbl/baz/bad => localhost:4178/a-integration/sbl/baz/bad
到目前为止我写了以下内容,但它只转发给 http://localhost:4178/a-integration/
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
String test = "http://localhost:4178/a-integration/";
return builder.routes()
.route("integration-test",
r -> r.path("/integration/sbl/**")
.uri(test)
)
.build();
}
如何修复上述代码以启用此行为?
编辑
我根据下面的回复尝试了以下方法
String samtykke = "http://localhost:4178/";
return builder.routes()
.route("samtykke", r -> r
.path("/gb-integration/sbl/**")
.filters(f -> f.rewritePath("/gb-integration/sbl/(?<segment>.*)", "/gb-samtykke-integration/${segment}"))
.uri(samtykke))
.build();
我尝试了 GET http://localhost:4177/gb-integration/sbl/api/sbl/income/ and expected http://localhost:4178/gb-samtykke-integration/api/sbl/income/ 返回,但没有成功。
输出显示:
2018-02-23 09:46:35.197 TRACE 6364 --- [ctor-http-nio-2] o.s.c.g.h.p.RoutePredicateFactory : Pattern "/gb-integration/sbl/**" matches against value "[path='/gb-integration/sbl/api/sbl/income/']"
2018-02-23 09:46:35.198 DEBUG 6364 --- [ctor-http-nio-2] o.s.c.g.h.RoutePredicateHandlerMapping : Route matched: samtykke
2018-02-23 09:46:35.198 DEBUG 6364 --- [ctor-http-nio-2] o.s.c.g.h.RoutePredicateHandlerMapping : Mapping [Exchange: GET http://localhost:4177/gb-integration/sbl/api/sbl/income/] to Route{id='samtykke', uri=http://localhost:4178/, order=0, predicate=org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda5/1803714790@1d0042df, gatewayFilters=[OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory$$Lambda7/485237151@77da026a, order=0}]}
2018-02-23 09:46:35.200 DEBUG 6364 --- [ctor-http-nio-2] o.s.c.g.handler.FilteringWebHandler : Sorted gatewayFilterFactories: [OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@5c534b5b}, order=-1}, OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory$$Lambda7/485237151@77da026a, order=0}, OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@396639b}, order=10000}, OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyRoutingFilter@a18649a}, order=2147483647}, OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.ForwardRoutingFilter@2b22a1cc}, order=2147483647}, OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@62573c86}, order=2147483647}]
2018-02-23 09:46:35.232 TRACE 6364 --- [ctor-http-nio-2] o.s.c.g.filter.RouteToRequestUrlFilter : RouteToRequestUrlFilter start
2018-02-23 09:46:35.314 TRACE 6364 --- [ctor-http-nio-1] o.s.c.g.filter.NettyWriteResponseFilter : NettyWriteResponseFilter start
您可以在路径过滤器中使用 rewritePath 功能,如此处文档所指定:
https://cloud.spring.io/spring-cloud-gateway/reference/html/#rewritepath-gatewayfilter-factory
相关部分:
5.12 RewritePath GatewayFilter Factory
The RewritePath GatewayFilter Factory takes a path regexp parameter
and a replacement parameter. This uses Java regular expressions for a
flexible way to rewrite the request path.
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.org
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /$\{segment}
For a request path of /foo/bar, this will set the path to /bar before
making the downstream request. Notice the $\ which is replaced with $
because of the YAML spec.
在您的示例中,它看起来像:
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
String test = "http://localhost:4178";
return builder.routes()
.route("integration-test", r -> r
.path("/integration/sbl/**")
.filters(f->f.rewritePath("/integration/(?<segment>.*)","/a-integration/${segment}"))
.uri(test)
)
.build();
}
请在下面找到完整设置的两种配置类型。两种方法产生相同的结果。
设置:
- 网关是 运行
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();
}
我们在这里 运行 遇到了类似的问题,虽然我同意 Boyen 的回应,但指出 "uri" 参数忽略了 "path" URI 的组成部分。这在文档中并不清楚(或者我至少没有找到它),所以我希望它能帮助其他人。
假设您想将在 /foo 收到的所有请求重定向到 http://example.org/bar
例如:/foo/x/y/z --> http://example.org/bar/x/y/z
例如,这按预期工作:
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.org
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /bar/$\{segment}
虽然这没有按预期工作(它忽略了 /bar):
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.org/bar
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /$\{segment}
注意到在使用 rewritePath 时更改 contextPath 的能力似乎被 Spring Boot 2.3.X 中的更改破坏了。并且 RewritePathGatewayFilterFactory.Config 不包含用于在 Hoxton.SR7+ 中传递新的 contextPath 的字段。
作为解决方法,我创建了自定义 RewritePathGatewayFilter 并使用了:
ServerHttpRequest request = exchange.getRequest().mutate().contextPath(newContextPath).path(newPath).build();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, request.getURI());
return chain.filter(exchange.mutate().request(request).build());
我正在使用 Spring Cloud Gateway 2.0.0.M6 测试一个简单的网关。我只想将一个 URL 转发给另一个 URL 使用 ** regex
示例 1:/integration/sbl/foo/bar => localhost:4178/a-integration/sbl/foo/bar
示例 2:/integration/sbl/baz/bad => localhost:4178/a-integration/sbl/baz/bad
到目前为止我写了以下内容,但它只转发给 http://localhost:4178/a-integration/
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
String test = "http://localhost:4178/a-integration/";
return builder.routes()
.route("integration-test",
r -> r.path("/integration/sbl/**")
.uri(test)
)
.build();
}
如何修复上述代码以启用此行为?
编辑
我根据下面的回复尝试了以下方法
String samtykke = "http://localhost:4178/";
return builder.routes()
.route("samtykke", r -> r
.path("/gb-integration/sbl/**")
.filters(f -> f.rewritePath("/gb-integration/sbl/(?<segment>.*)", "/gb-samtykke-integration/${segment}"))
.uri(samtykke))
.build();
我尝试了 GET http://localhost:4177/gb-integration/sbl/api/sbl/income/ and expected http://localhost:4178/gb-samtykke-integration/api/sbl/income/ 返回,但没有成功。
输出显示:
2018-02-23 09:46:35.197 TRACE 6364 --- [ctor-http-nio-2] o.s.c.g.h.p.RoutePredicateFactory : Pattern "/gb-integration/sbl/**" matches against value "[path='/gb-integration/sbl/api/sbl/income/']"
2018-02-23 09:46:35.198 DEBUG 6364 --- [ctor-http-nio-2] o.s.c.g.h.RoutePredicateHandlerMapping : Route matched: samtykke
2018-02-23 09:46:35.198 DEBUG 6364 --- [ctor-http-nio-2] o.s.c.g.h.RoutePredicateHandlerMapping : Mapping [Exchange: GET http://localhost:4177/gb-integration/sbl/api/sbl/income/] to Route{id='samtykke', uri=http://localhost:4178/, order=0, predicate=org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda5/1803714790@1d0042df, gatewayFilters=[OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory$$Lambda7/485237151@77da026a, order=0}]}
2018-02-23 09:46:35.200 DEBUG 6364 --- [ctor-http-nio-2] o.s.c.g.handler.FilteringWebHandler : Sorted gatewayFilterFactories: [OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@5c534b5b}, order=-1}, OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory$$Lambda7/485237151@77da026a, order=0}, OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@396639b}, order=10000}, OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.NettyRoutingFilter@a18649a}, order=2147483647}, OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.ForwardRoutingFilter@2b22a1cc}, order=2147483647}, OrderedGatewayFilter{delegate=GatewayFilterAdapter{delegate=org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@62573c86}, order=2147483647}]
2018-02-23 09:46:35.232 TRACE 6364 --- [ctor-http-nio-2] o.s.c.g.filter.RouteToRequestUrlFilter : RouteToRequestUrlFilter start
2018-02-23 09:46:35.314 TRACE 6364 --- [ctor-http-nio-1] o.s.c.g.filter.NettyWriteResponseFilter : NettyWriteResponseFilter start
您可以在路径过滤器中使用 rewritePath 功能,如此处文档所指定:
https://cloud.spring.io/spring-cloud-gateway/reference/html/#rewritepath-gatewayfilter-factory
相关部分:
5.12 RewritePath GatewayFilter Factory
The RewritePath GatewayFilter Factory takes a path regexp parameter and a replacement parameter. This uses Java regular expressions for a flexible way to rewrite the request path.
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.org
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /$\{segment}
For a request path of /foo/bar, this will set the path to /bar before making the downstream request. Notice the $\ which is replaced with $ because of the YAML spec.
在您的示例中,它看起来像:
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {
String test = "http://localhost:4178";
return builder.routes()
.route("integration-test", r -> r
.path("/integration/sbl/**")
.filters(f->f.rewritePath("/integration/(?<segment>.*)","/a-integration/${segment}"))
.uri(test)
)
.build();
}
请在下面找到完整设置的两种配置类型。两种方法产生相同的结果。
设置:
- 网关是 运行
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();
}
我们在这里 运行 遇到了类似的问题,虽然我同意 Boyen 的回应,但指出 "uri" 参数忽略了 "path" URI 的组成部分。这在文档中并不清楚(或者我至少没有找到它),所以我希望它能帮助其他人。
假设您想将在 /foo 收到的所有请求重定向到 http://example.org/bar
例如:/foo/x/y/z --> http://example.org/bar/x/y/z
例如,这按预期工作:
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.org
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /bar/$\{segment}
虽然这没有按预期工作(它忽略了 /bar):
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.org/bar
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /$\{segment}
注意到在使用 rewritePath 时更改 contextPath 的能力似乎被 Spring Boot 2.3.X 中的更改破坏了。并且 RewritePathGatewayFilterFactory.Config 不包含用于在 Hoxton.SR7+ 中传递新的 contextPath 的字段。
作为解决方法,我创建了自定义 RewritePathGatewayFilter 并使用了:
ServerHttpRequest request = exchange.getRequest().mutate().contextPath(newContextPath).path(newPath).build();
exchange.getAttributes().put(GATEWAY_REQUEST_URL_ATTR, request.getURI());
return chain.filter(exchange.mutate().request(request).build());