Java+Spring5非阻塞式文件上传实现方案问询
简洁实现Spring 5非阻塞式文件上传
我太懂你这种找简洁示例的痛苦了!官方文档写得太冗长,网上很多示例又堆砌了一堆没必要的代码,看得人头大。下面给你一个极简版的Spring 5(WebFlux)非阻塞文件上传实现,直接抄就能用:
1. 基础依赖(Maven为例)
先把核心依赖加到你的pom.xml里,用Spring Boot Starter能省掉一堆手动配置:
<dependencies> <!-- Spring WebFlux 核心依赖,对应Spring 5.x --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> <version>2.7.15</version> <!-- 该版本兼容Spring 5.3核心 --> </dependency> </dependencies>
如果是纯Spring 5项目,记得手动引入spring-webflux和Netty容器依赖。
2. 核心控制器代码
这是最关键的非阻塞上传逻辑,没有多余的包装,直接处理文件并保存:
import org.springframework.http.MediaType; import org.springframework.http.codec.multipart.FilePart; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; import java.nio.file.Path; import java.nio.file.Paths; @RestController public class NonBlockingUploadController { // 自定义上传目录,可根据需求修改 private static final Path UPLOAD_DIR = Paths.get("./uploads"); static { // 初始化上传目录,避免文件保存失败 if (!UPLOAD_DIR.toFile().exists()) { UPLOAD_DIR.toFile().mkdirs(); } } @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public Mono<String> uploadSingleFile(@RequestPart("file") FilePart filePart) { // 非阻塞式保存文件,transferTo方法返回Mono<Void>表示异步操作完成 return filePart.transferTo(UPLOAD_DIR.resolve(filePart.filename())) .then(Mono.just("文件上传成功:" + filePart.filename())); } }
关键说明:
FilePart是WebFlux专为非阻塞文件上传设计的类型,替代了传统Servlet的MultipartFiletransferTo方法完全是非阻塞的,底层依赖响应式IO操作,不会阻塞线程- 整个方法返回
Mono<String>,完全贴合Spring WebFlux的响应式编程模型
3. 测试上传
用curl就能快速测试,替换成你本地的文件路径:
curl -X POST -F "file=@/Users/xxx/Documents/test.txt" http://localhost:8080/upload
也可以用Postman:选POST请求,地址填http://localhost:8080/upload,Body选form-data,Key设为file,类型选File,然后选择本地文件上传即可。
4. 进阶:多文件上传
如果需要支持同时上传多个文件,只需要把参数改成Flux<FilePart>即可:
@PostMapping(value = "/upload-multiple", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public Mono<String> uploadMultipleFiles(@RequestPart("files") Flux<FilePart> fileParts) { return fileParts .flatMap(filePart -> filePart.transferTo(UPLOAD_DIR.resolve(filePart.filename()))) .then(Mono.just("所有文件上传完成")); }
测试多文件上传的curl命令:
curl -X POST -F "files=@/Users/xxx/Documents/file1.txt" -F "files=@/Users/xxx/Documents/file2.jpg" http://localhost:8080/upload-multiple
内容的提问来源于stack exchange,提问作者Sergey Karpushin
相关产品推荐
相关产品推荐

