问题场景
spring boot 版本:2.2.2
应用网关:shenyu网关(soul网关)
错误描述
在一次项目中,我在上传文件时被网关拦截出现了这个问题:
databufferlimitexception: exceeded limit on max bytes to buffer :262144
发现只能上传256kb以下的文件,但现在文件随便就是10m或者更大。
具体错误如下:
org.springframework.core.io.buffer.databufferlimitexception: exceeded limit on max bytes to buffer : 262144
at org.springframework.core.io.buffer.limiteddatabufferlist.raiselimitexception(limiteddatabufferlist.java:101)
suppressed: reactor.core.publisher.fluxonassembly$onassemblyexception:
stack trace:
at org.springframework.core.io.buffer.limiteddatabufferlist.raiselimitexception(limiteddatabufferlist.java:101)
at org.springframework.core.io.buffer.limiteddatabufferlist.updatecount(limiteddatabufferlist.java:94)
at
解决方案
方案一(对我不生效)
一般来说直接设置 max-in-memory-size 就可以生效
spring:
codec:
max-in-memory-size: 100mb但是以上代码在spring2.x.x版本中不生效,官方说解决了,估计是在后面版本解决了,但是项目都上生产了肯定不可能现在来换版本,所以只有另想办法,在他启动中debug发现在初始化代码时已经设置为262144了:

方案二(有效)
于是继续往上发现在 org.springframework.core.codec.abstractdatabufferdecoder中进行初始化的,于是诞生了写一个同名类来给他初始化,利用spring中同名bean相互覆盖的特性,在我们注入了同名bean就会优先使用我们的类。
层级目录如下:

我们要保证这个类的包名和spring的名称一模一样,具体代码不变,只需修改maxinmemorysize 大小,如下所示:
package org.springframework.core.codec;
import java.util.map;
import org.reactivestreams.publisher;
import org.springframework.core.resolvabletype;
import org.springframework.core.io.buffer.databuffer;
import org.springframework.core.io.buffer.databufferutils;
import org.springframework.lang.nullable;
import org.springframework.util.mimetype;
import reactor.core.publisher.flux;
import reactor.core.publisher.mono;
/**
* @auther: whhh
* @date: 2021/4/7 11:08
* @description: 图片上传重写缓存区大小,解决上传图片缓存不够问题
*/
public abstract class abstractdatabufferdecoder<t> extends abstractdecoder<t> {
//图片上传重写缓存区大小,解决上传图片缓存不够问题
private int maxinmemorysize = 1024*1024*100;
protected abstractdatabufferdecoder(mimetype... supportedmimetypes) {
super(supportedmimetypes);
}
public void setmaxinmemorysize(int bytecount) {
this.maxinmemorysize = bytecount;
}
public int getmaxinmemorysize() {
return this.maxinmemorysize;
}
public flux<t> decode(publisher<databuffer> input, resolvabletype elementtype, @nullable mimetype mimetype, @nullable map<string, object> hints) {
return flux.from(input).map((buffer) -> {
return this.decodedatabuffer(buffer, elementtype, mimetype, hints);
});
}
public mono<t> decodetomono(publisher<databuffer> input, resolvabletype elementtype, @nullable mimetype mimetype, @nullable map<string, object> hints) {
return databufferutils.join(input, this.maxinmemorysize).map((buffer) -> {
return this.decodedatabuffer(buffer, elementtype, mimetype, hints);
});
}
/** @deprecated */
@deprecated
@nullable
protected t decodedatabuffer(databuffer buffer, resolvabletype elementtype, @nullable mimetype mimetype, @nullable map<string, object> hints) {
return this.decode(buffer, elementtype, mimetype, hints);
}
}
重点就是这里,他会去读取这个配置:

到这里我们的问题就解决了,上传文件就成功了。

总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论