拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 SpringCloudGateway未正确转发

SpringCloudGateway未正确转发

白鹭 - 2022-03-11 2138 0 0

我有一个 Spring Boot 应用程序正在尝试使用 Spring Cloud Gateway 访问一些微服务。我正在使用的代码基于在以下位置阅读的说明:

https://betterjavacode.com/programming/how-to-use-api-gateway-with-spring-cloud

基本上,我的应用程序复制了该站点上提供的代码,包括作者创建的两个测验微服务:

@RestController
@RequestMapping("/vendor")
public class VendorController
{
    @GetMapping("/total")
    public List vendors()
    {
        List list = new ArrayList<>();
        list.add("CJI Consultants");
        list.add("Signature Consultants");
        list.add("Deloitte");
        return list;
    }
}

@RestController
@RequestMapping("/customer")
public class CustomerController
{
    @GetMapping("/total")
    public List customers()
    {
        List list = new ArrayList<>();
        list.add("Microsoft");
        list.add("Amazon");
        list.add("Apple");
        return list;
    }
}

我的实际网关代码与作者的类似:

包 com.betterjavacode.apigatewaydemo.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class SpringCloudConfig
{
    @Bean
    public RouteLocator gatewayRoutes(RouteLocatorBuilder routeLocatorBuilder)
    {
        return routeLocatorBuilder.routes()
                .route("customerModule", rt -> rt.path("/customer/**")
                        .uri("http://localhost:8081/"))
                .route("vendorModule", rt -> rt.path("/vendor/**")
                    .uri("http://localhost:8082/"))
                    .build();

    }
}

不幸的是,当我运行这个应用程序时,输入正确的 URL:

http://localhost:8080/vendor/total

http://localhost:8080/customer/total

我收到 404 错误!

我似乎能够通过网关访问这两个微服务的唯一方法是将路径更改为“/**”。例如,为了访问客户微服务,我必须更改:

.route("customerModule", rt -> rt.path("/customer/**") .uri("http://localhost:8081/"))

v.route("customerModule", rt -> rt.path("/**") .uri("http://localhost:8081/"))

然后我可以毫无问题地看到客户微服务输出。当然,我不能对两条路线使用相同的路径。看起来这个网关只能处理一个使用“/**”路径的路由。

我在这里错过了什么吗?有人可以说明为什么这不能正常作业吗?我怎样才能让这个网关转发到它应该去的路径?

uj5u.com热心网友回复:

您可以尝试使用StripPrefix自变量。

return routeLocatorBuilder.routes()
                .route("customerModule", rt -> rt.path("/customer/**")
                        .filters(f -> f.stripPrefix(0))
                        .uri("http://localhost:8081/"))
                .route("vendorModule", rt -> rt.path("/vendor/**")
                    .filters(f -> f.stripPrefix(0))
                    .uri("http://localhost:8082/"))
                    .build();

或者您可以洗掉 @RequestMapping("/customer") 和 @RequestMapping("/vendor") 因为它会在将前缀路径发送到下游之前洗掉它。

uj5u.com热心网友回复:

我相信我已经解决了这个问题。事实证明,由于未知原因,每当在网关中使用“/**”以外的路由时,URI 都不能包含 HTTP 前缀。

换句话说,而不是有一个路线:

route("customerModule", rt -> rt.path("/customer/**")
                    .uri("http://localhost:8081/"))

路由应该没有 HTTP 前缀:

.route("customerModule", rt -> rt.path("/customer/**")
                    .uri("localhost:8081/"))

我不知道为什么会这样,但确实如此。只要我格式化不带前缀的 uri,我就可以访问微服务。

我偶然发现了这一点。我很想知道为什么它会这样作业,但至少应该记录这个要求。

标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *