You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Cloud Gateway MVC路径重写及路由调用URL排查问题

Spring Cloud Gateway MVC路由404问题排查与解决

问题场景

使用Spring Boot搭配Spring Cloud Gateway MVC,现有两台服务器:

  • 服务器1:localhost:8082,上下文路径为/crm
  • 服务器2:localhost:8001,上下文路径为/acme/crm

需求是:当调用服务器1的localhost:8082/crm/bff/book/1时,转发至服务器2的localhost:8001/acme/crm/book/1。但以下路由配置出现404错误:

@Bean
public RouterFunction<ServerResponse> inventoryServiceRoute() {
    return route("crm_bff")
            .route(RequestPredicates.path("/bff/**"), http("http://localhost:8001/acme/crm"))
            .before(rewritePath("/(?<segment>.*)", "/${segment}"))
            .build();
}

404问题原因

  1. 路径匹配规则不准确:服务器1的上下文路径是/crm,实际请求路径为/crm/bff/**,但原配置用RequestPredicates.path("/bff/**")匹配,无法命中正确的请求。
  2. 路径重写逻辑错误:原重写规则/(?<segment>.*)没有处理请求路径中的/crm/bff前缀,导致转发后的路径不符合服务器2的接口要求。

修正后的路由配置

调整路径重写规则,并优化路径匹配(可选但更精准),修正后的代码如下:

@Bean
public RouterFunction<ServerResponse> inventoryServiceRoute() {
    return route("crm_bff")
            // 匹配包含服务器1上下文路径的完整请求路径
            .route(RequestPredicates.path("/crm/bff/**"), http("http://localhost:8001"))
            // 将/crm/bff/xxx重写为/acme/crm/xxx,匹配服务器2的上下文路径+目标接口
            .before(rewritePath("/crm/bff/(?<segment>.*)", "/acme/crm/${segment}"))
            .build();
}

注:也可以保持原路径匹配/bff/**,但需要确保网关的上下文路径配置正确,不过显式匹配/crm/bff/**更不容易出错。

查看网关实际转发URL的方法

方法1:开启调试日志

在配置文件中添加日志级别配置,打印网关转发的详细信息:

logging:
  level:
    org.springframework.cloud.gateway: DEBUG
    org.springframework.web.reactive.function.client: DEBUG

启动服务后,日志中会输出转发的目标URL、请求参数、响应状态等细节。

方法2:添加自定义前置过滤器

在路由配置中加入自定义逻辑,直接打印目标URL:

@Bean
public RouterFunction<ServerResponse> inventoryServiceRoute() {
    return route("crm_bff")
            .route(RequestPredicates.path("/crm/bff/**"), http("http://localhost:8001"))
            .before(exchange -> {
                // 获取网关转发的目标URI
                URI targetUri = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);
                System.out.println("网关实际转发URL: " + targetUri);
                return Mono.empty();
            })
            .before(rewritePath("/crm/bff/(?<segment>.*)", "/acme/crm/${segment}"))
            .build();
}

每次请求转发时,控制台会直接输出实际调用的URL。

内容的提问来源于stack exchange,提问作者robert trudel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 01:10:16