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

Spring Cloud Gateway自定义GlobalFilter修改查询参数方法

在Spring Cloud Gateway中修改请求查询参数

我在Spring Boot 2.7.0版本的项目中配置了Spring Cloud Gateway,需求是在自定义的org.springframework.cloud.gateway.filter.GlobalFilter中修改请求的查询参数值。例如Postman发起的请求为http://localhost:8080/employee/message?q1=abc&q2=123,期望经过过滤器转发后的请求为http://localhost:8080/employee/message?q1=xyz&q2=789,让后端控制器获取到修改后的参数值。目前我能在过滤器中获取到查询参数,但不清楚具体如何修改,以下是我编写的自定义Filter代码:

@Component
public class PreFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        
        ServerWebExchange modExchange = changeQueryParams(exchange);
        return chain.filter(modExchange);
    }
    
    private static ServerWebExchange changeQueryParams(ServerWebExchange exchange)  {
        ServerHttpRequest request = exchange.getRequest();
        
        Map<String, List<String>> map = new HashMap<>();
        map.put("q1", Arrays.asList("xyz"));
        map.put("q2", Arrays.asList("789"));
        MultiValueMap<String, String> newMultiValueMap = new LinkedMultiValueMap<>(map);
        
        Builder builder = request.mutate();
        request = builder.uri(UriComponentsBuilder.fromUri(exchange.getRequest()
                .getURI())
              .replaceQueryParams(newMultiValueMap)
              .build()
              .toUri()).build();

        ServerWebExchange modifiedExchange = exchange.mutate().request(request).build();
        return modifiedExchange;
    }
}

解决方案

你的代码核心思路是对的,但直接覆盖所有查询参数会丢失请求中未指定修改的其他参数。以下是优化后的实现,既能精准修改目标参数,又能保留原始请求的其他参数:

@Component
public class PreFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerWebExchange modifiedExchange = modifyQueryParams(exchange);
        return chain.filter(modifiedExchange);
    }

    private ServerWebExchange modifyQueryParams(ServerWebExchange exchange) {
        ServerHttpRequest originalRequest = exchange.getRequest();
        // 获取原始查询参数,保留未修改的参数
        MultiValueMap<String, String> originalQueryParams = originalRequest.getQueryParams();
        
        // 基于原始参数创建新映射,修改指定参数值
        MultiValueMap<String, String> newQueryParams = new LinkedMultiValueMap<>(originalQueryParams);
        newQueryParams.set("q1", "xyz");
        newQueryParams.set("q2", "789");

        // 构建包含新查询参数的URI
        URI newUri = UriComponentsBuilder.fromUri(originalRequest.getURI())
                .replaceQueryParams(newQueryParams)
                .build()
                .toUri();

        // 创建修改后的请求对象
        ServerHttpRequest modifiedRequest = originalRequest.mutate()
                .uri(newUri)
                .build();

        // 返回更新后的Exchange对象
        return exchange.mutate().request(modifiedRequest).build();
    }
}

关键步骤说明

  1. 保留原始参数:通过originalRequest.getQueryParams()获取所有原始查询参数,避免丢失未指定修改的参数
  2. 修改目标参数:使用set方法直接替换指定参数的值,若参数不存在则自动新增
  3. 重构请求URI:借助UriComponentsBuilder重新生成包含新查询参数的URI
  4. 更新请求上下文:通过request.mutate()创建新的请求对象,替换到ServerWebExchange中传递给后续过滤器链

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 08:45:39