Amby
Amby

Reputation: 462

Spring reactive big image files giving nosuchfileexception and not sent using Webclient

I am writing a code to send multiple big images of size 10MB after receiving from the front end. The objective is to do the processing of the images in the background and send the response immediately to front end interface.

Below is the piece of code which receive the request from frontend

@PostMapping(value = "/submit")
    public Mono<ResponseEntity<String>> handleFormSubmit(ServerWebExchange serverWebExchange) {
        return serverWebExchange.getMultipartData()
                .filter(map -> !CollectionUtils.isEmpty(map))
                .doOnNext(map -> {
                    asynchronousService.handlerAsync(map).subscribe();
                })
                .map(filePart -> ResponseEntity.ok("success"))
                .switchIfEmpty(Mono.just(ResponseEntity.badRequest().body("bad")));
    }

Below piece of code send the images received to the other server using webclient

Asynchronous Service

public Mono<Void> handlerAsync(MultiValueMap<String,Part> fileParts) {
        MultipartBodyBuilder multipartBodyBuilder = new MultipartBodyBuilder();
        fileParts.forEach((key,value)->{
            FilePart filePart= (FilePart) value.get(0);
            multipartBodyBuilder.asyncPart(filePart.name(), filePart.content(), DataBuffer.class)
                    .filename(filePart.filename()).header("DocType","INSPECTION");
        });
        MultiValueMap<String, HttpEntity<?>> requestBody = multipartBodyBuilder.build();
        return WebClient.builder()
                .codecs(clientCodecConfigurer -> clientCodecConfigurer.defaultCodecs().maxInMemorySize(1024*1024*16))
                .build()
                .post().uri("http://localhost:8081/receive")
                .bodyValue(requestBody)
                .retrieve()
                .onStatus(httpStatusCode -> httpStatusCode.is4xxClientError() || httpStatusCode.is5xxServerError(), cr ->
                     cr.createException().map(webClientResponseException -> {
                        System.out.println(webClientResponseException.getResponseBodyAsString());
                        System.out.println(webClientResponseException.getStatusCode());
                        return webClientResponseException;
                    }))
                .bodyToMono(Void.class)
                .retryWhen(Retry.fixedDelay(2, Duration.ofSeconds(2)))
                .onErrorResume(throwable -> {
                    if (Exceptions.isRetryExhausted(throwable)) {
                        Mono.error(new RuntimeException("retry exhausted"));
                    }
                    return Mono.error(new RuntimeException("error"));
                });
    
        }

It is working fine when the images are in KB size but for bigger image file size it is giving an error as below.

java.nio.file.NoSuchFileException: /tmp/spring-multipart-12155021382861713953/10508329666633429299.multipart
    at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92) ~[na:na]
    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:106) ~[na:na]
    at java.base/sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:111) ~[na:na]
    at java.base/sun.nio.fs.UnixFileSystemProvider.newByteChannel(UnixFileSystemProvider.java:218) ~[na:na]
    at java.base/java.nio.file.Files.newByteChannel(Files.java:380) ~[na:na]

Upvotes: 0

Views: 26

Answers (1)

Hantsy
Hantsy

Reputation: 9321

The following block could not finished when the request is handled and returned to the client.

.doOnNext(map -> {
     asynchronousService.handlerAsync(map).subscribe();
 })

Try to use .then() instead and have a try.

Alternatively, change the in-memory size of Codecs via the property spring.codec.max-in-memory-size.

In our real-world applications, we have a lot of upload cases similar to this. eg. Uploading files from our clients, the server side receives it and sends it to other storage, such as S3 or Sftp, etc. All cases worked well.

Check my example of uploading files and storing in MongoDB.

Upvotes: 0

Related Questions