1

我正在将旧的 jHipster 网关更新到 7.5.0 版本。新版本使用 Spring Cloud Gateway(带有 Eureka),而旧版本使用 Zuul。在以前的版本中,使用名为“foo”和路径“bar”的服务发现服务会在网关上注册它而没有任何前缀,因此可以通过以下方式访问它:

GATEWAY_URL/foo/bar

现在所有服务都使用“services/”前缀注册,结果需要调用以下网址:

GATEWAY_URL/services/foo/bar

我找不到对此负责的配置。我找到了一个属性 spring.webservices.path,但是将其更改为其他值不会产生任何更改,并且在 Spring Boot 2.6.3 中,它的值不能为空或“/”(但我不确定这是否是我应该的属性检查)。我还尝试了 spring.cloud.gateway.routes 形式:

spring:
webservices:
    path: /test
main:
    allow-bean-definition-overriding: true
cloud:
    gateway:
        discovery:
            locator:
                enabled: true
        routes:
            - id: user-service-route
              uri: lb://user
              predicates:
                  - Path=/user/**

但没有任何运气。我也不确定这是 jHipster 问题还是 SCG

我需要更改它,以便使用我的 API 的其他系统不需要更新它们的路径,我知道我之前总是可以添加 nginx 以便它会重写路径,但感觉不正确。

4

1 回答 1

1

此行为由 SCG 自动配置 - GatewayDiscoveryClientAutoConfiguration 完成,它使用谓词注册 DiscoveryLocatorProperties bean:

PredicateDefinition{name='Path', args={pattern='/'+serviceId+'/**'}}

我不想更改自动配置,所以我做了 WebFilter,它作为第一个执行并改变请求路径

public class ServicesFilter implements WebFilter {

private final ServicesMappingConfigration mapping;

public ServicesFilter(ServicesMappingConfigration mapping) {
    this.mapping = mapping;
}

@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
    RequestPath path = exchange.getRequest().getPath();
    if (path.elements().size() > 1) {
        PathContainer pathContainer = path.subPath(1, 2);
        if (mapping.getServices().contains(pathContainer.value())) {
            ServerHttpRequest mutatedRequest = exchange
                .getRequest()
                .mutate()
                .path("/services" + exchange.getRequest().getPath())
                .build();
            ServerWebExchange mutatedExchange = exchange.mutate().request(mutatedRequest).build();
            return chain.filter(mutatedExchange);
        }
    }

    return chain.filter(exchange);
}}
于 2022-01-29T20:36:01.923 回答