配置 Spring 网关以将 Web 请求转发到内部 url
Configure Spring Gateway to forward web requests to internal url
我有 Spring 具有以下 Gradle 依赖项的网关应用程序:
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-gateway'
implementation 'com.netflix.eureka:eureka-core'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
路线配置:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder, LoggingGatewayFilterFactory loggingFactory) {
return builder.routes()
.route("service_route_clients_summary", r -> r.path("c")
.filters(f -> f.rewritePath("/api/management/home/clients/summary", "/management/home/clients/summary")
.filter(loggingFactory.apply(new LoggingGatewayFilterFactory.Config("My Custom Message", true, true))))
.uri("lb://merchant-hub-admin-service:8000/management/home/clients/summary"))
.build();
}
我想转发 /api/management/home/clients/summary
到内部 link /management/home/clients/summary
但使用 Eureka 客户端查找内部服务。
当我运行代码时没有任何反应 - 找不到路径。
知道哪里出了问题吗?
简短版本,您传递给 routes().route 的参数不正确。
你应该尝试这样的事情:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route(p -> p.path(" /api/management/home/clients/summary **")
.filters(gatewayFilterSpec -> gatewayFilterSpec
.rewritePath("/management/home/clients/summary/(?<remaining>.*)"
, "/home/clients//${remaining}"))
.uri("lb:///home/clients/summary/"))
.build();
}
您可以根据您的要求添加 trim 和 url 的过滤器表达式。
下面的配置将使 url 成为 /api/management ==> /management
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/api/**
filters:
- RewritePath=/api(?<segment>/?.*), /$\{segment}
对于尤里卡发现,您可以这样做:
spring:
application:
name: gateway
cloud:
gateway:
discovery:
locator:
lowerCaseServiceId: true
enabled: true
predicates:
- name: Path
args:
pattern: "'/api/'+serviceId.toLowerCase()+'/**'"
filters:
- name: RewritePath
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
当然,您的主 class 中需要 @EnableDiscoveryClient
。
如果有兴趣,可以查看我的 test repos.
之一
在 eureka 中检查 /eureka/app 并查看您的服务的元数据。您将看到该服务是否具有上下文路径。如果没有,上面的配置将起作用。
如果服务确实有上下文路径,您需要在 replacement
键中使用 followwing:
replacement: "{metadata.get('contextPath') != null ? metadata.get('contextPath') : ''} + '/${remaining}'"
我有 Spring 具有以下 Gradle 依赖项的网关应用程序:
implementation group: 'org.springframework.cloud', name: 'spring-cloud-starter-gateway'
implementation 'com.netflix.eureka:eureka-core'
implementation 'org.springframework.cloud:spring-cloud-starter-netflix-eureka-client'
implementation 'org.springframework.boot:spring-boot-starter-actuator'
路线配置:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder, LoggingGatewayFilterFactory loggingFactory) {
return builder.routes()
.route("service_route_clients_summary", r -> r.path("c")
.filters(f -> f.rewritePath("/api/management/home/clients/summary", "/management/home/clients/summary")
.filter(loggingFactory.apply(new LoggingGatewayFilterFactory.Config("My Custom Message", true, true))))
.uri("lb://merchant-hub-admin-service:8000/management/home/clients/summary"))
.build();
}
我想转发 /api/management/home/clients/summary
到内部 link /management/home/clients/summary
但使用 Eureka 客户端查找内部服务。
当我运行代码时没有任何反应 - 找不到路径。 知道哪里出了问题吗?
简短版本,您传递给 routes().route 的参数不正确。
你应该尝试这样的事情:
@Bean
public RouteLocator routes(RouteLocatorBuilder builder) {
return builder.routes()
.route(p -> p.path(" /api/management/home/clients/summary **")
.filters(gatewayFilterSpec -> gatewayFilterSpec
.rewritePath("/management/home/clients/summary/(?<remaining>.*)"
, "/home/clients//${remaining}"))
.uri("lb:///home/clients/summary/"))
.build();
}
您可以根据您的要求添加 trim 和 url 的过滤器表达式。
下面的配置将使 url 成为 /api/management ==> /management
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: https://example.org
predicates:
- Path=/api/**
filters:
- RewritePath=/api(?<segment>/?.*), /$\{segment}
对于尤里卡发现,您可以这样做:
spring:
application:
name: gateway
cloud:
gateway:
discovery:
locator:
lowerCaseServiceId: true
enabled: true
predicates:
- name: Path
args:
pattern: "'/api/'+serviceId.toLowerCase()+'/**'"
filters:
- name: RewritePath
args:
regexp: "'/api/' + serviceId.toLowerCase() + '/(?<remaining>.*)'"
replacement: "'/${remaining}'"
当然,您的主 class 中需要 @EnableDiscoveryClient
。
如果有兴趣,可以查看我的 test repos.
在 eureka 中检查 /eureka/app 并查看您的服务的元数据。您将看到该服务是否具有上下文路径。如果没有,上面的配置将起作用。
如果服务确实有上下文路径,您需要在 replacement
键中使用 followwing:
replacement: "{metadata.get('contextPath') != null ? metadata.get('contextPath') : ''} + '/${remaining}'"