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

如何在Spring Cloud Gateway的ModifyRequestBodyGatewayFilterFactory中增大缓冲区上限

解决自定义ModifyRequestBodyGatewayFilter的DataBufferLimitException问题

你遇到的问题是因为自定义的ModifyRequestBody过滤器在读取请求体时,使用的是默认256KB的缓冲区限制,而全局的spring.codec.max-in-memory-size和WebFluxConfigurer配置不会直接作用于这个过滤器的请求体读取逻辑。以下是适配ModifyRequestBody场景的解决方案:

步骤1:在过滤器配置类中添加缓冲区大小参数

首先,在自定义过滤器的内部配置类中新增maxInMemorySize属性,用于接收自定义的缓冲区上限:

public class CustomModifyRequestBodyGatewayFilterFactory extends ModifyRequestBodyGatewayFilterFactory {

    public CustomModifyRequestBodyGatewayFilterFactory() {
        super(Config.class);
    }

    public static class Config extends ModifyRequestBodyGatewayFilterFactory.Config {
        // 默认保持256KB,可通过配置修改
        private int maxInMemorySize = 262144;

        public int getMaxInMemorySize() {
            return maxInMemorySize;
        }

        public void setMaxInMemorySize(int maxInMemorySize) {
            this.maxInMemorySize = maxInMemorySize;
        }
    }

    // 后续apply方法修改见步骤2
}

步骤2:修改请求体读取逻辑,指定缓冲区上限

在过滤器的apply方法中,替换原有的请求体读取代码,显式使用自定义的maxInMemorySize限制。这里提供两种实现方式:

方式一:使用DataBufferUtils.join指定限制

直接操作DataBuffer流,通过DataBufferUtils.join的重载方法指定缓冲区上限:

@Override
public GatewayFilter apply(Config config) {
    return (exchange, chain) -> {
        // 获取自定义的缓冲区大小
        int maxSize = config.getMaxInMemorySize();

        // 读取请求体时指定上限
        return DataBufferUtils.join(exchange.getRequest().getBody(), maxSize)
                .flatMap(dataBuffer -> {
                    // 将DataBuffer转换为字节数组(根据你的业务需求调整)
                    byte[] requestBody = new byte[dataBuffer.readableByteCount()];
                    dataBuffer.read(requestBody);
                    DataBufferUtils.release(dataBuffer);

                    // 这里替换成你的请求体处理逻辑,比如修改body后重新构建请求
                    ModifiedServerHttpRequest modifiedRequest = new ModifiedServerHttpRequest(
                            exchange.getRequest(), requestBody);

                    return chain.filter(exchange.mutate().request(modifiedRequest).build());
                })
                .onErrorResume(DataBufferLimitException.class, ex -> {
                    // 可选:自定义异常处理逻辑
                    return Mono.error(new IllegalArgumentException("请求体大小超过限制"));
                });
    };
}

方式二:通过ServerRequest和BodyExtractors指定限制

利用Spring WebFlux的ServerRequest和BodyExtractors,显式设置读取上限:

// 需要注入ServerCodecConfigurer获取messageReaders
private final ServerCodecConfigurer serverCodecConfigurer;

public CustomModifyRequestBodyGatewayFilterFactory(ServerCodecConfigurer serverCodecConfigurer) {
    super(Config.class);
    this.serverCodecConfigurer = serverCodecConfigurer;
}

@Override
public GatewayFilter apply(Config config) {
    return (exchange, chain) -> {
        int maxSize = config.getMaxInMemorySize();
        ServerRequest serverRequest = ServerRequest.create(exchange, serverCodecConfigurer.getReaders());

        // 使用BodyExtractors指定maxInMemorySize
        return serverRequest.body(BodyExtractors.toMono(byte[].class).maxInMemorySize(maxSize))
                .flatMap(requestBody -> {
                    // 你的请求体处理逻辑,比如修改后构建新请求
                    ModifiedServerHttpRequest modifiedRequest = new ModifiedServerHttpRequest(
                            exchange.getRequest(), requestBody);
                    return chain.filter(exchange.mutate().request(modifiedRequest).build());
                });
    };
}

步骤3:配置过滤器的缓冲区大小

在网关配置文件(如application.yml)中,为自定义过滤器指定缓冲区上限:

spring:
  cloud:
    gateway:
      routes:
        - id: your_route_id
          uri: http://your_target_service
          filters:
            - name: CustomModifyRequestBody # 你的过滤器名称
              args:
                maxInMemorySize: 5242880 # 5MB,根据需求调整

关键说明

全局的spring.codec.max-in-memory-size和WebFluxConfigurer的配置之所以无效,是因为ModifyRequestBodyGatewayFilterFactory的默认实现是直接操作原始DataBuffer流,并未复用全局配置的HttpMessageReader读取逻辑,因此必须在过滤器内部显式指定缓冲区上限。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 04:47:07