Spring Boot 版本:2.6.6
Spring Cloud Gateway 版本:3.1.1
由于在 Gateway 的自定义过滤器中重写了请求 ServerRequest
,后面因为升级了架构,原本旧版本未对请求参数的大小进行限制(默认取-1),后面升级了新版修改为 256KB 的限制。
方案一跟二对于我当然版本的 SpringBoot 不生效,大家可以都尝试一下,有可能可以。
一、设置配置文件(失败)
spring:
codec:
max-in-memory-size: 50MB
二、添加配置 Bean(失败)
@Configuration
@EnableWebFlux
public class WebFluxWebConfig implements WebFluxConfigurer
{
@Override
public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
configurer.defaultCodecs().maxInMemorySize(50 * 1024 * 1024);
}
}
三、手动设置配置类 ServerCodecConfigurer
(成功)
博主的场景是拿出请求的 body,由于只能取一次需要重新创建 Request,create 的第二个参数就是 Readers
// 第二个参数 redaers 是从 ServerCodecConfigurer 获取的
ServerRequest serverRequest = ServerRequest.create(exchange, readers);
该方案是在 Github Spring 仓库的 issue 看到的解决方案,结合自己的实际场景改的,是否有效还得自己尝试一下。
@Autowired
private ServerCodecConfigurer serverCodecConfigurer;
@PostConstruct
public void init() {
ServerCodecConfigurer.ServerDefaultCodecs serverDefaultCodecs = serverCodecConfigurer.defaultCodecs();
// 设置限制 50MB
serverDefaultCodecs.maxInMemorySize(50 * 1024 * 1024);
}
通过设置默认的 maxInMemorySize
会将原有的所有 Readers 实现类删除,并根据你设置的大小重新新建,因此只需要在初始化时设置即可。由于会新建对象,务必不要在过滤器的方法中设置,造成不必要的性能损耗。
/**
* Reset and initialize typed readers.
* @since 5.3.3
*/
protected void initTypedReaders() {
// 删除所有 Readers
this.typedReaders.clear();
// 重新添加 Readers
addCodec(this.typedReaders, new DecoderHttpMessageReader<>(new ByteArrayDecoder()));
// 略...
}
addCodec 方法会重新设置 reader 的 maxInMemorySize 大小
/**
* Initialize a codec and add it to the List.
* @since 5.1.13
*/
protected <T> void addCodec(List<T> codecs, T codec) {
initCodec(codec);
codecs.add(codec);
}
private void initCodec(@Nullable Object codec) {
// 略...
Integer size = this.maxInMemorySize;
if (size != null) {
if (codec instanceof AbstractDataBufferDecoder) {
// 重新设置的大小
((AbstractDataBufferDecoder<?>) codec).setMaxInMemorySize(size);
}
}
// 略...
}
该文章对你有帮助吗?别忘了点赞加关注•᷄ࡇ•᷅