springCloud gateway 替换请求体

该博客介绍了如何在Spring Cloud Gateway中实现过滤器,动态替换HTTP请求体。通过创建一个`GlobalFilter`,利用`ServerHttpRequestDecorator`装饰器模式,读取原始请求体,解析为JSON,添加新的属性,然后返回新的`DataBuffer`。这个过程有助于在微服务架构中统一处理和增强入站请求。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

springCloud gateway 替换请求体

/**
 * @author :chenqiwei
 * @date :Created in 2021/7/12 11:41
 */
@Component
public class MyFilter implements GlobalFilter {


    private final DataBufferFactory dataBufferFactory = new NettyDataBufferFactory(ByteBufAllocator.DEFAULT);

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("123456");
        ServerHttpRequest request = exchange.getRequest();

        // 新建一个ServerHttpRequest装饰器,覆盖需要装饰的方法
        ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(request) {

            @Override
            public Flux<DataBuffer> getBody() {
                Flux<DataBuffer> body = super.getBody();
                InputStreamHolder holder = new InputStreamHolder();
//                InputStream inputStream;
                body.subscribe(buffer -> {
                    holder.inputStream = buffer.asInputStream();
                });
                if (null != holder.inputStream) {
                    try {
                        // 解析JSON的节点
                        JsonNode jsonNode = objectMapper.readTree(holder.inputStream);
                        Assert.isTrue(jsonNode instanceof ObjectNode, "JSON格式异常");
                        ObjectNode objectNode = (ObjectNode) jsonNode;
                        // JSON节点最外层写入新的属性
                        objectNode.put("name", "网关过滤器添加");
                        DataBuffer dataBuffer = dataBufferFactory.allocateBuffer();
                        String json = objectNode.toString();
                        System.out.println("最终的JSON数据为:{}"+ json);
                        dataBuffer.write(json.getBytes(StandardCharsets.UTF_8));
                        return Flux.just(dataBuffer);
                    } catch (Exception e) {
                        throw new IllegalStateException(e);
                    }
                } else {
                    return super.getBody();
                }
            }
        };
        // 使用修改后的ServerHttpRequestDecorator重新生成一个新的ServerWebExchange
        return chain.filter(exchange.mutate().request(decorator).build());

//        return chain.filter(exchange);
    }
}
### 解决 Spring Cloud Gateway 中 GET 请求携带中文参数的问题 在 Spring Cloud Gateway 处理 GET 请求时,如果 URL 参数包含中文字符,默认情况下可能会遇到编码问题。为了确保这些参数能够被正确解析和传递给下游服务,需要采取一些措施来调整默认行为。 #### 方法一:配置全局 URI 编解码器设置 通过自定义 `ServerCodecConfigurer` 来覆盖默认的编解码器配置,使得所有的路径变量以及查询字符串都能按照 UTF-8 进行编码: ```java import org.springframework.context.annotation.Bean; import org.springframework.http.codec.ServerCodecConfigurer; @Configuration public class CodecConfig { @Bean public ServerCodecConfigurer serverCodecConfigurer() { return ServerCodecConfigurer.create(builder -> builder.defaultCharset(StandardCharsets.UTF_8)); } } ``` 此方法适用于所有类型的 HTTP 请求,并且只需一次配置即可生效[^1]。 #### 方法二:针对特定路由设定过滤器 对于某些特殊场景下仅需对部分路由做处理的情况,则可以在创建 RouteDefinition Bean 的时候加入专门用于转换字符集的 GlobalFilter 或者 GatewayFilter 工厂函数来进行局部定制化改造: ```java @Bean public GlobalFilter customGlobalFilter() { return (exchange, chain) -> { exchange.getRequest().mutate() .uri(uriBuilder -> uriBuilder.replaceQuery( UriUtils.encodeQueryParam(exchange.getRequest().getQueryParams(), "UTF-8")) ).build(); return chain.filter(exchange); }; } ``` 这段代码片段展示了如何利用 `UriComponentsBuilder` 和 `UriUtils` 类库提供的工具方法重新构建带有正确编码后的 query string 的新 URI 对象替换原始请求对象内的旧值;之后再继续沿用原来的 filter 链执行后续逻辑[^2]. 另外需要注意的一点是在实际开发环境中应当尽量避免直接操作 HttpHeader ,尤其是在 COMITTED 状态之后更不应该尝试去更改任何 header 字段的内容以免引发未知错误。因此建议尽可能早地完成必要的预处理工作比如上面提到过的字符集转义等操作[^3].
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值