正文

SpringBoot?集成MongoDB实现文件上传功能(springboot集成mongodb存储Geojson)硬核推荐

文章摘要

这篇文章介绍了基于MongoDB和Spring Boot实现的文件管理服务。该服务实现了上传、下载和删除文件的功能。上传时,根据文件大小选择存储在MongoDB本地或GridFS中;下载时,从GridFS或本地存储获取文件,并在下载完成后自动删除对应的存储文件。文章还涉及了依赖注入、流式处理、文件后缀处理以及对MongoDB和GridFS的操作,体现了对MongoDB存储结构和GridFS存储策略的优化处理。核心功能包括文件上传、下载和删除,支持高效的大文件管理。

import cn.hutool.core.io.IoUtil; import cn.hutool.core.util.IdUtil; import com.coisini.mongodb.model.MongoFile; import com.coisini.mongodb.repository.MongoFileRepository; import com.coisini.mongodb.service.FileUploadService; import com.coisini.mongodb.util.MD5Util; import com.coisini.mongodb.vo.FileExportVo; import com.mongodb.client.gridfs.GridFSBucket; import com.mongodb.client.gridfs.GridFSDownloadStream; import com.mongodb.client.gridfs.model.GridFSFile; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.bson.types.Binary; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.query.Criteria; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.gridfs.GridFsResource; import org.springframework.data.mongodb.gridfs.GridFsTemplate; import org.springframework.stereotype.Service; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.List; import java.util.Objects; import java.util.Optional; import java.util.stream.Collectors; @Slf4j @Service(“fileMongoServiceImpl”) @RequiredArgsConstructor(onConstructor=@__(@Autowired)) public class FileMongoServiceImpl implements FileUploadService { private final MongoFileRepository mongoFileRepository; private final MongoTemplate mongoTemplate; private final GridFsTemplate gridFsTemplate; private final GridFSBucket gridFSBucket; @Override public List<FileExportVo> uploadFiles(List<MultipartFile> files) { return files.stream().map(file -> { try { return this.uploadFile(file); } catch (Exception e) { log.error(“文件上传失败”, e); return null; } }).filter(Objects::nonNull).collect(Collectors.toList()); } @Override public FileExportVo uploadFile(MultipartFile file) throws Exception { if (file.getSize() > 16777216) { return this.saveGridFsFile(file); } else { return this.saveBinaryFile(file); } } @Override public FileExportVo downloadFile(String fileId) { Optional<MongoFile> option=this.getBinaryFileById(fileId); if (option.isPresent()) { MongoFile mongoFile=option.get(); if(Objects.isNull(mongoFile.getContent())){ option=this.getGridFsFileById(fileId); } } return option.map(FileExportVo::new).orElse(null); } @Override public void removeFile(String fileId) { Optional<MongoFile> option=this.getBinaryFileById(fileId); if (option.isPresent()) { if (Objects.nonNull(option.get().getGridFsId())) { this.removeGridFsFile(fileId); } else { this.removeBinaryFile(fileId); } } } public void removeBinaryFile(String fileId) { mongoFileRepository.deleteById(fileId); } public void removeGridFsFile(String fileId) { // TODO 根据id查询文件 MongoFile mongoFile=mongoTemplate.findById(fileId, MongoFile.class ); if(Objects.nonNull(mongoFile)){ // TODO 根据文件ID删除fs.files和fs.chunks中的记录 Query deleteFileQuery=new Query().addCriteria(Criteria.where(“filename”).is(mongoFile.getGridFsId())); gridFsTemplate.delete(deleteFileQuery); // TODO 删除集合mongoFile中的数据 Query deleteQuery=new Query(Criteria.where(“id”).is(fileId)); mongoTemplate.remove(deleteQuery, MongoFile.class); } } public FileExportVo saveBinaryFile(MultipartFile file) throws Exception { String suffix=getFileSuffix(file); MongoFile mongoFile=mongoFileRepository.save( MongoFile.builder() .fileName(file.getOriginalFilename()) .fileSize(file.getSize()) .content(new Binary(file.getBytes())) .contentType(file.getContentType()) .uploadDate(new Date()) .suffix(suffix) .md5(MD5Util.getMD5(file.getInputStream())) .build() ); return new FileExportVo(mongoFile); } public FileExportVo saveGridFsFile(MultipartFile file) throws Exception { String suffix=getFileSuffix(file); String gridFsId=this.storeFileToGridFS(file.getInputStream(), file.getContentType()); MongoFile mongoFile=mongoTemplate.save( MongoFile.builder() .fileName(file.getOriginalFilename()) .fileSize(file.getSize()) .contentType(file.getContentType()) .uploadDate(new Date()) .suffix(suffix) .md5(MD5Util.getMD5(file.getInputStream())) .gridFsId(gridFsId) .build() ); return new FileExportVo(mongoFile); } public String storeFileToGridFS(InputStream in, String contentType){ String gridFsId=IdUtil.simpleUUID(); // TODO 将文件存储进GridFS中 gridFsTemplate.store(in, gridFsId , contentType); return gridFsId; } public Optional<MongoFile> getBinaryFileById(String id) { return mongoFileRepository.findById(id); } public Optional<MongoFile> getGridFsFileById(String id){ MongoFile mongoFile=mongoTemplate.findById(id , MongoFile.class ); if(Objects.nonNull(mongoFile)){ Query gridQuery=new Query().addCriteria(Criteria.where(“filename”).is(mongoFile.getGridFsId())); try { // TODO 根据id查询文件 GridFSFile fsFile=gridFsTemplate.findOne(gridQuery); // TODO 打开流下载对象 GridFSDownloadStream in=gridFSBucket.openDownloadStream(fsFile.getObjectId()); if(in.getGridFSFile().getLength() > 0){ // TODO 获取流对象 GridFsResource resource=new GridFsResource(fsFile, in); // TODO 获取数据 mongoFile.setContent(new Binary(IoUtil.readBytes(resource.getInputStream()))); return Optional.of(mongoFile); }else { return Optional.empty(); } }catch (IOException e){ log.error(“获取MongoDB大文件失败”, e); } } return Optional.empty(); } private String getFileSuffix(MultipartFile file) { String suffix=””; if (Objects.requireNonNull(file.getOriginalFilename()).contains(“.”)) { suffix=file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(“.”)); } return suffix; } }