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(); } }
关键步骤说明
- 保留原始参数:通过
originalRequest.getQueryParams()获取所有原始查询参数,避免丢失未指定修改的参数 - 修改目标参数:使用
set方法直接替换指定参数的值,若参数不存在则自动新增 - 重构请求URI:借助
UriComponentsBuilder重新生成包含新查询参数的URI - 更新请求上下文:通过
request.mutate()创建新的请求对象,替换到ServerWebExchange中传递给后续过滤器链
内容的提问来源于stack exchange,提问作者Vinit
相关产品推荐
相关产品推荐

