问题
I am using Spring Cloud Gateway 2.0.0.M6 testing a simple gateway. I just want a URL to be forwarded to another URL with ** regex
Example 1: /integration/sbl/foo/bar => localhost:4178/a-integration/sbl/foo/bar
Example 2: /integration/sbl/baz/bad => localhost:4178/a-integration/sbl/baz/bad
So far I have written the following, but it only forwards to 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();
}
How can I fix the above code to enable this behaviour?
EDIT
I tried the following based on response below
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();
and I tried a GET http://localhost:4177/gb-integration/sbl/api/sbl/income/ and expected http://localhost:4178/gb-samtykke-integration/api/sbl/income/ back but it didn't work.
The output says:
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$$Lambda$245/1803714790@1d0042df, gatewayFilters=[OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.RewritePathGatewayFilterFactory$$Lambda$247/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$$Lambda$247/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
回答1:
You can use the rewritePath functionality in your path filters, as specified by the documentation found here :
https://cloud.spring.io/spring-cloud-gateway/reference/html/#rewritepath-gatewayfilter-factory
Relevant parts :
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.
In your example, that would look like :
@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();
}
回答2:
We were running a similar issue here, and although I agree with Boyen's response, it may be useful to point out that the "uri" parameter ignores the "path" component of the URI. This is not clear in the documentation (or I haven't found it at least), so I hope it helps others.
Suppose you want to redirect all the requests received at /foo to http://example.org/bar
For example: /foo/x/y/z --> http://example.org/bar/x/y/z
For instance this WORKS AS EXPECTED:
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.org
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /bar/$\{segment}
While this DOES NOT WORK as expected (it ignores /bar):
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.org/bar
predicates:
- Path=/foo/**
filters:
- RewritePath=/foo/(?<segment>.*), /$\{segment}
回答3:
Please find below the two types of configuration with a full set-up. Both methods produce the same result.
Set-up:
- the gateway is running on
http://localhost:8090
- a base path called
/context
serves as the entry point of the gateway - a service called
my-resources
running onhttp://localhost:8091/my-resources
. When/my-resources
is invoked without parameters, it returns all resources. When it is invoked with a parameters it returns the resource with the correspondingRID
(if any)
The gateway is configured so that all path variables (possibly none) transmitted to http://localhost:8090/context/my-resources/
is forwarded to uri http://localhost:8091/my-resources/
.
Method 1: using 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
Method 2: using Java like configuration
@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();
}
回答4:
Noticed the ability to change contextPath when using rewritePath appears broken by changes in Spring Boot 2.3.X. And RewritePathGatewayFilterFactory.Config does not contain a field for passing a new contextPath in Hoxton.SR7+.
As a workaround I created a custom RewritePathGatewayFilter and used:
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());
来源:https://stackoverflow.com/questions/48865174/spring-cloud-gateway-proxy-forward-the-entire-sub-part-of-url