如何在WebFlux过滤器中正确修改请求Query参数
WebFlux过滤器中修改请求查询参数的实现方案
异常原因
直接调用request.getQueryParams().add()抛出UnsupportedOperationException的核心原因是:ServerHttpRequest返回的查询参数集合是不可变只读集合,本身不支持增删改操作,所有直接操作原集合的修改逻辑都会触发该异常。
正确实现逻辑
WebFlux的请求、交换器对象都遵循不可变设计,修改属性时不能直接操作原实例,需要通过装饰器模式构造新的实例,再传入过滤链即可。
完整实现代码
import org.springframework.http.server.reactive.ServerHttpRequest; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebFilter; import org.springframework.web.server.WebFilterChain; import org.springframework.web.util.UriComponentsBuilder; import reactor.core.publisher.Mono; import java.net.URI; public class MyFilter implements WebFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { ServerHttpRequest originalRequest = exchange.getRequest(); // 复制原有查询参数为可修改的集合 MultiValueMap<String, String> editableQueryParams = new LinkedMultiValueMap<>(originalRequest.getQueryParams()); // 新增/修改/删除自定义参数 editableQueryParams.add("key1", "value1"); // 构建携带新参数的URI URI modifiedUri = UriComponentsBuilder.fromUri(originalRequest.getURI()) .replaceQueryParams(editableQueryParams) .build() .toUri(); // 构造新的请求实例 ServerHttpRequest modifiedRequest = originalRequest.mutate() .uri(modifiedUri) .build(); // 构造新的交换器实例,替换原请求 ServerWebExchange modifiedExchange = exchange.mutate() .request(modifiedRequest) .build(); // 传入修改后的交换器继续过滤链逻辑 return chain.filter(modifiedExchange); } }
注意事项
- 不要尝试通过反射等方式直接修改原请求的内部属性,会破坏WebFlux的响应式编程模型,引发线程安全问题
- 构造新URI时必须使用
UriComponentsBuilder处理参数,避免手动拼接字符串导致的URL编码错误、多值参数丢失问题 - 如果需要同时修改请求头、请求体内容,也可以通过相同的mutate装饰器模式实现,逻辑完全一致
内容的提问来源于stack exchange,提问作者MikeFootEater
相关产品推荐
相关产品推荐

