DataBufferLimitException: Limit für maximale Bytes zum Puffern des Webflux-Fehlers überschritten

Lesezeit: 4 Minuten

Benutzer-Avatar
gefahren

Beim Senden einer Datei erhalte ich ein Array von Bytes. Ich habe immer ein Problem mit Webflux ein Array zu erhalten. Der Fehler wird wie folgt ausgelöst:

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

Weißt du jetzt, wie man das in Webflux löst?

Benutzer-Avatar
Guru Cse

Das hat bei mir funktioniert:

  1. Ein … kreieren @Bean in einer Ihrer Konfigurationsklassen oder der main SpringBootApplication Klasse:

    @Bean
    public WebClient webClient() {
        final int size = 16 * 1024 * 1024;
        final ExchangeStrategies strategies = ExchangeStrategies.builder()
            .codecs(codecs -> codecs.defaultCodecs().maxInMemorySize(size))
            .build();
        return WebClient.builder()
            .exchangeStrategies(strategies)
            .build();
    }
    
  2. Gehen Sie als Nächstes zu Ihrer gewünschten Klasse, in der Sie die verwenden möchten WebClient:

    @Service
    public class TestService {
    
        @Autowired
        private WebClient webClient;
    
        public void test() {
            String out = webClient
                .get()
                .uri("/my/api/endpoint")
                .retrieve()
                .bodyToMono(String.class)
                .block();
    
            System.out.println(out);
        }
    }
    

  • Ich weiß nicht warum, dies ist die einzige Lösung, die mit WebFlux 2.3.2.RELEASE funktioniert hat

    – zerologiko

    28. September 2020 um 23:10 Uhr

  • Wenn Sie eine benutzerdefinierte Webkonfiguration deklariert haben (z. B. durch Implementieren von WebMvcConfigurer), überschreiben Sie die Option in properties.yaml. Wenn Sie also die maxInMemorySize -Eigenschaft konfigurieren Sie direkt Ihren Webclient und umgehen die Webkonfiguration von spring-boot.

    – Georgios Syngouroglou

    17. Dezember 2021 um 1:00 Uhr


Benutzer-Avatar
David

Ich nehme an, bei diesem Problem geht es darum, eine neue hinzuzufügen spring.codec.max-in-memory-size Konfigurationseigenschaft in Spring Boot. Fügen Sie es hinzu application.yml Datei wie:

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

  • Ich verwende dies in meiner Spring-Boot-App-Konfiguration, es hilft jedoch nicht.

    – mareck_ste

    17. Juni 2020 um 16:29 Uhr

  • @mareck_ste Hallo! Möglicherweise verwenden Sie eine benutzerdefinierte Konfiguration, die diese Option außer Kraft setzt. Sie haben z. B. eine WebClient-Konfiguration, also legen Sie einfach diese ‘maxInMemorySize’-Eigenschaft in diesem WebClientBuilder.exchangeStrategies() fest.

    – David

    18. Juni 2020 um 17:14 Uhr

  • @mareck_ste in der Tat, ich habe das gleiche für spring-boot-starter-webflux 2.3.5-RELEASE . Schauen Sie sich diese hervorragende Antwort an

    – Bernhard Paulus

    12. November 2020 um 23:16 Uhr


  • Danke Bernard, das Modifizieren der Codecs hat funktioniert.

    – Bobine

    25. Mai um 7:50 Uhr

  • Wenn die obige konfigurationsbasierte Lösung nicht funktioniert – das Folgende könnte erklären, warum – müssen Sie den vorkonfigurierten Spring WebClient.Builder verwenden und keinen eigenen erstellen github.com/spring-projects/spring-boot/issues/27836

    – kellyfj

    7. Juli um 20:57 Uhr


Benutzer-Avatar
Nikodemus Ojwee

Stellen Sie das Maximum ein Byte (in Megabyte) in deiner Frühlingsstiefel application.properties Konfigurationsdatei wie unten:

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

Ich habe diesen Fehler für einen einfachen RestController erhalten (ich poste eine große JSON-Zeichenfolge).

Hier ist, wie ich die erfolgreich geändert habe 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);
    }
}

das war überraschend schwer zu finden

hat bei mir funktioniert

webTestClient.mutate().codecs(configurer -> configurer
  .defaultCodecs()
  .maxInMemorySize(16 * 1024 * 1024)).build().get()
  .uri("/u/r/l")
  .exchange()
  .expectStatus()
  .isOk()

  • Vielen Dank!! Ich bin mir nicht sicher, warum Eigenschaften oder Bean für Webclient bei mir nicht funktioniert haben, aber das hat funktioniert!

    – JayC

    30. März um 1:02

Anstatt Daten sofort abzurufen, können Sie Folgendes streamen:

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

Alternativ in Stream umwandeln:

    .map(b -> b.asInputStream(true))
    .reduce(SequenceInputStream::new)
    .map(stream -> {
        // consume stream
        stream.close();
        return string;
    });

In den meisten Fällen möchten Sie den Stream nicht wirklich aggregieren, sondern ihn direkt verarbeiten. Die Notwendigkeit, große Datenmengen in den Speicher zu laden, ist meistens ein Zeichen dafür, den Ansatz zu einem reaktiveren zu ändern. JSON- und XML-Parser haben Streaming-Schnittstellen.

  • Vielen Dank!! Ich bin mir nicht sicher, warum Eigenschaften oder Bean für Webclient bei mir nicht funktioniert haben, aber das hat funktioniert!

    – JayC

    30. März um 1:02

Benutzer-Avatar
Mohnisch

Das hat bei mir funktioniert

val exchangeStrategies = ExchangeStrategies.builder()
                .codecs { configurer: ClientCodecConfigurer -> configurer.defaultCodecs().maxInMemorySize(16 * 1024 * 1024) }.build()
        return WebClient.builder().exchangeStrategies(exchangeStrategies).build()

1176130cookie-checkDataBufferLimitException: Limit für maximale Bytes zum Puffern des Webflux-Fehlers überschritten

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy