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

如何使用Spring Cloud API Gateway (MVC)实现请求参数转路径的动态过滤器?

在Spring Cloud API Gateway (MVC)中转换查询参数为路径参数

需求说明

需要处理GET请求,将带查询参数的请求路径转换为路径参数形式:

  • 原始请求:v1/sample-resource/methodName?id=id12345
  • 目标请求:v1/sample-resource/methodName/id12345

当前使用的依赖版本:

id 'org.springframework.boot' version '3.3.1'
implementation 'org.springframework.cloud:spring-cloud-starter-gateway-mvc'

现有尝试代码

文件路径:com/example/demo/routes/RouteConfiguration.java

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouterAddRequestParam() {
        return route("add_request_parameter_route")
                .GET("v1/resource-name/id12345/methodName", http("https://example.org"))
                .before(
                        rewritePath("v1/resource-name/(?<segment>.*)", "v1/resource-name/methodName")
                                .andThen(addRequestParameter("id", "id12345"))
                )
                .build();
    }
}

解决方案

你的现有代码存在两个核心问题:路由匹配规则与原始请求不匹配,且未实现动态提取查询参数值。以下是修正后的实现:

1. 核心实现思路

  • 匹配原始请求路径v1/sample-resource/methodName,且要求携带id查询参数
  • 从请求中动态提取id参数的值
  • 重写请求路径,将查询参数转为路径参数
  • 可选移除原查询参数,避免传递到下游服务

2. 修正后的代码(直接处理请求方式)

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouter() {
        return route("query_to_path_param_route")
                // 匹配原始请求路径及带id参数的GET请求
                .GET("v1/sample-resource/methodName", request -> {
                    // 动态获取id查询参数,无参数时抛出异常
                    String id = request.queryParam("id").orElseThrow(() -> 
                        new IllegalArgumentException("id参数不能为空"));
                    
                    // 构造目标路径
                    String rewrittenPath = String.format("v1/sample-resource/methodName/%s", id);
                    
                    // 修改请求路径并移除原查询参数
                    ServerHttpRequest modifiedRequest = request.mutate()
                            .path(rewrittenPath)
                            .queryParams(params -> params.remove("id"))
                            .build();
                    
                    // 转发到下游服务,替换为你的实际服务地址
                    return ServerResponse.status(HttpStatus.OK)
                            .build(http("https://example.org").exchange(modifiedRequest));
                })
                .build();
    }
}

3. Filter链式调用写法

如果偏好使用Filter链式处理,可自定义前置Filter实现:

@Configuration
class RouteConfiguration {

    @Bean
    public RouterFunction<ServerResponse> gatewayRouterWithFilter() {
        return route("query_to_path_param_filter_route")
                .GET("v1/sample-resource/methodName", http("https://example.org"))
                .before(request -> {
                    // 提取id参数
                    String id = request.queryParam("id").orElseThrow(() -> 
                        new IllegalArgumentException("id参数不能为空"));
                    // 拼接新路径
                    String newPath = request.path() + "/" + id;
                    // 修改请求并移除原查询参数
                    return request.mutate()
                            .path(newPath)
                            .queryParams(params -> params.remove("id"))
                            .build();
                })
                .build();
    }
}

关键注意点

  • 路由匹配规则必须对应原始请求路径,而非目标路径
  • 用request.queryParam("id")动态获取参数值,避免硬编码
  • 通过request.mutate()修改请求对象,确保下游收到正确的路径参数
  • 若id为可选参数,可移除orElseThrow,改为设置默认值或跳过路径重写逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:03:22