Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java DataBufferLimitException:超出缓冲区webflux的最大字节数限制错误_Java_Spring_Webclient_Spring Webflux - Fatal编程技术网

Java DataBufferLimitException:超出缓冲区webflux的最大字节数限制错误

Java DataBufferLimitException:超出缓冲区webflux的最大字节数限制错误,java,spring,webclient,spring-webflux,Java,Spring,Webclient,Spring Webflux,发送文件时,我收到一个字节数组。我总是遇到webflux接收数组的问题。 引发的错误如下所示: org.springframework.core.io.buffer.DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144 at org.springframework.core.io.buffer.LimitedDataBufferList.raiseLimitException(LimitedDat

发送文件时,我收到一个字节数组。我总是遇到webflux接收数组的问题。 引发的错误如下所示:

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

您现在知道如何在webflux中解决这个问题了吗?

我想这个问题是关于在spring Boot中添加一个新的spring.codec.max-in-memory-size配置属性。将其添加到属性中,如:

spring:
  codec:
    max-in-memory-size: 10MB

spring boot配置文件中设置最大字节数(在兆字节数中),如下所示:

spring.codec.max-in-memory-size=20MB

我在一个简单的RestController中遇到了这个错误(我发布了一个大的json字符串)

下面是我如何成功更改
maxInMemorySize

import org.springframework.context.annotation.Configuration;
import org.springframework.http.codec.ServerCodecConfigurer;
import org.springframework.web.reactive.config.ResourceHandlerRegistry;
import org.springframework.web.reactive.config.WebFluxConfigurer;

@Configuration
public class WebfluxConfig implements WebFluxConfigurer {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {

        registry.addResourceHandler("/swagger-ui.html**")
            .addResourceLocations("classpath:/META-INF/resources/");

        registry.addResourceHandler("/webjars/**")
            .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

    @Override
    public void configureHttpMessageCodecs(ServerCodecConfigurer configurer) {
        configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024);
    }
}
这对我来说是很难找到的

  • 在配置类或主Springbootapplication类中创建一个bean

    @Bean
    public WebClient getWebClientBuilder(){
        return   WebClient.builder().exchangeStrategies(ExchangeStrategies.builder()
                .codecs(configurer -> configurer
                          .defaultCodecs()
                          .maxInMemorySize(16 * 1024 * 1024))
                        .build())
                      .build();
    }
    
  • 接下来转到您想要使用webclient的所需类

      @RestController / @Bean/ @Service
       public class PaySharpGatewayController {
            @Autowired
            WebClient webClient;
    
            public void test(){
             String out = webClient
                          .get()
                          .uri("end point of an API")
                          .retrieve()
                          .bodyToMono(String.class)
                         .block();
    
             sysout(out)
            }
    

  • 您可以流式传输以下内容,而不是一次检索数据:

    Mono<String> string = webClient.get()
        .uri("end point of an API")
        .retrieve()
        .bodyToFlux(DataBuffer.class)
        .map(buffer -> {
            String string = buffer.toString(Charset.forName("UTF-8"));
            DataBufferUtils.release(buffer);
            return string;
        });
    

    在大多数情况下,您不希望真正聚合流,而不是直接处理它。需要在内存中加载大量数据,这在很大程度上是将这种方法转变为更被动的方法的标志。JSON和XML解析器具有流式接口。

    另一种选择是创建自定义的
    codecustomizer
    ,它将同时应用于
    WebFlux
    WebClient

    @配置
    类MyAppConfiguration{
    伴星{
    私有常量val MAX_MEMORY_SIZE=50*1024*1024//50 MB
    }
    @豆子
    有趣的CodeCustomizer():CodeCustomizer{
    返回编解码器自定义程序{
    it.defaultCodecs()
    .maxInMemorySize(最大内存大小)
    }
    }
    }
    
    这对我很有效

    val exchangeStrategies = ExchangeStrategies.builder()
                    .codecs { configurer: ClientCodecConfigurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024) }.build()
            return WebClient.builder().exchangeStrategies(exchangeStrategies).build()
    
    webTestClient.mutate().codecs(configurer -> configurer
      .defaultCodecs()
      .maxInMemorySize(16 * 1024 * 1024)).build().get()
      .uri("/u/r/l")
      .exchange()
      .expectStatus()
      .isOk()
    
    为我工作

    val exchangeStrategies = ExchangeStrategies.builder()
                    .codecs { configurer: ClientCodecConfigurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024) }.build()
            return WebClient.builder().exchangeStrategies(exchangeStrategies).build()
    
    webTestClient.mutate().codecs(configurer -> configurer
      .defaultCodecs()
      .maxInMemorySize(16 * 1024 * 1024)).build().get()
      .uri("/u/r/l")
      .exchange()
      .expectStatus()
      .isOk()
    

    谢谢,这是因为我在我的spring boot应用程序配置中使用了它,但是它没有帮助。@mareck_ste Hi!可能您正在使用一些覆盖此选项的自定义配置。例如,您有WebClient配置,所以只需在WebClient Builder.ExchangeStrages()@mareck_ste中设置此“maxInMemorySize”属性即可。事实上,我对spring boot starter webflux 2.3.5-RELEASE也有相同的配置。看看这里,缓冲区是在哪里定义的?@AshokKoyi我之前混淆了两个变量(已修复)您实际测量了总体内存占用吗?i、 e即使在释放数据缓冲区之后,除非您使用最后一个流,否则内存仍然会堆积,因为您正在使用reduce,直到收到最后一个字节。因此,我不确定使用这种方法是否会有任何优势选项(1)有问题,因为不能保证在将字节转换为字符串之前收到所有数据。在映射操作期间,我们可能只读取4字节UTF-8字符中的1字节。如果可以利用部分数据&释放缓冲区,这是最好的办法。使用归约是一个坏主意,因为我们正在填充内存,直到完成归约,这就破坏了在缓冲区出现时使用缓冲区的意义。选项(1)是有效的,但它只作为字节数组,而不是字符串数组。我不知道为什么,这是在WebFlux 2.3.2.RELEASE上工作的唯一解决方案