目录

问题场景

错误描述

解决方案

方案一(对我不生效)

方案二(有效)


 

问题场景

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);
    }
}

重点就是这里,他会去读取这个配置:

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

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐