java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > springboot出现DataBufferLimitException: Exceeded limit on max bytes to buffer:262144

springboot出现DataBufferLimitException: Exceeded limit on max bytes to buffer:262144问题及解决

作者:我真的不吃辣条

在Shenyu网关中,上传大文件时遇到`DataBufferLimitException`异常,问题在于Spring Boot 2版本中`max-in-memory-size`配置无效,通过创建同名类并修改`maxInMemorySize`值来解决问题,此方法利用Spring同名Bean覆盖机制,确保自定义类优先被加载

问题场景

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

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

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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文