如何将Mono<FilePart>转换为byte[]并将Excel文件存入MongoDB?
响应式编程实现Excel文件存储到MongoDB方案
1. 前置准备
首先确保项目已引入Spring Data MongoDB Reactive依赖,定义响应式仓库接口:
import org.springframework.data.mongodb.repository.ReactiveMongoRepository; import org.springframework.stereotype.Repository; @Repository public interface ExcelRepository extends ReactiveMongoRepository<Excel, Integer> { }
注意:实体类中的id属性若使用int类型需自行处理主键生成逻辑,建议改为Integer或MongoDB原生的ObjectId类型避免主键冲突;同时请为Excel类添加对应的getter、setter方法,保证属性可正常读写
2. 修正Controller层代码
原Controller返回值不符合响应式规范,需调整为返回Mono<HttpStatus>:
@PostMapping(path = "/file", consumes = MediaType.MULTIPART_FORM_DATA_VALUE, produces = MediaType.APPLICATION_STREAM_JSON_VALUE) public Mono<HttpStatus> uploadFile(@RequestPart("files") Mono<FilePart> file) { return excelService.save(file); }
3. 实现Service层存储逻辑
Service层返回值调整为Mono<HttpStatus>,核心逻辑是将FilePart的响应式数据流合并为字节数组,封装为实体后存入MongoDB:
import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DataBufferUtils; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Service; import reactor.core.publisher.Mono; @Service public class ExcelService { private final ExcelRepository excelRepository; // 构造注入Repository public ExcelService(ExcelRepository excelRepository) { this.excelRepository = excelRepository; } public Mono<HttpStatus> save(Mono<FilePart> filePartMono) { return filePartMono // 读取文件所有内容合并为单个DataBuffer .flatMap(filePart -> DataBufferUtils.join(filePart.content())) // 将DataBuffer转为字节数组 .map(dataBuffer -> { byte[] fileBytes = new byte[dataBuffer.readableByteCount()]; dataBuffer.read(fileBytes); // 释放内存避免泄漏 DataBufferUtils.release(dataBuffer); // 构建Excel实体 Excel excel = new Excel(); excel.setFile(fileBytes); return excel; }) // 调用响应式仓库保存数据 .flatMap(excelRepository::save) // 保存成功返回201状态码 .thenReturn(HttpStatus.CREATED) // 异常场景返回500状态码 .onErrorReturn(HttpStatus.INTERNAL_SERVER_ERROR); } }
补充说明
如果需要处理大于16MB的Excel文件,超出MongoDB单文档大小限制,不适合直接存byte数组,建议改用MongoDB GridFS实现响应式大文件存储。
内容的提问来源于stack exchange,提问作者Koni
相关产品推荐
相关产品推荐

