Spring 反应式大图像文件给出 nosuchfileException 并且不使用 Webclient 发送

问题描述 投票:0回答:1

我正在编写一个代码,从前端接收后发送多张大小为10MB的大图片。目的是在后台处理图像并将响应立即发送到前端界面。

下面是接收前端请求的代码

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

下面的代码使用 webclient 将收到的图像发送到其他服务器

异步服务

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

当图像大小为 KB 时,它工作正常,但对于更大的图像文件大小,则会出现如下错误。

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]
spring-boot file spring-webflux spring-webclient
1个回答
0
投票

当请求被处理并返回给客户端时,以下块无法完成。

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

尝试使用

.then()
来代替并尝试一下。

或者,通过属性

Codecs
更改
spring.codec.max-in-memory-size
的内存大小。

在我们的实际应用中,我们有很多类似这样的上传案例。 例如。从我们的客户端上传文件,服务器端接收它并将其发送到其他存储,例如S3或Sftp等。所有情况都运行良好。

查看我上传文件并存储到 MongoDB 的示例

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.