经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 数据库/运维 » MongoDB » 查看文章
SpringBoot?集成MongoDB实现文件上传功能
来源:jb51  时间:2022/4/18 10:10:54  对本文有异议

前言

  • 记录下SpringBoot集成MongoDB实现文件上传的步骤
  • MongoDB - 5.0.6安装包

链接: https://pan.baidu.com/s/1_7nJDe3ndraNyo3vGWOXhg?pwd=i4cv 
提取码: i4cv 

环境

SpringBoot - 2.5.12
MongoDB - 5.0.6

代码实现

pom.xml

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-starter-web</artifactId>
  4. </dependency>
  5. <!-- mongodb -->
  6. <dependency>
  7. <groupId>org.springframework.boot</groupId>
  8. <artifactId>spring-boot-starter-data-mongodb</artifactId>
  9. </dependency>
  10. <!-- lombok -->
  11. <dependency>
  12. <groupId>org.projectlombok</groupId>
  13. <artifactId>lombok</artifactId>
  14. </dependency>
  15. <!-- hutool -->
  16. <dependency>
  17. <groupId>cn.hutool</groupId>
  18. <artifactId>hutool-all</artifactId>
  19. <version>4.5.1</version>
  20. </dependency>

application.yml

  1. server:
  2. port: 31091
  3.  
  4. spring:
  5. servlet:
  6. multipart:
  7. max-file-size: 100MB
  8. data:
  9. mongodb:
  10. host: 127.0.0.1
  11. port: 27017
  12. database: admin
  13. username: root
  14. password: sunday
  15.  
  16. fileUploadService:
  17. impl: fileMongoServiceImpl

MongoConfig.java

  1. import com.mongodb.client.MongoClient;
  2. import com.mongodb.client.MongoDatabase;
  3. import com.mongodb.client.gridfs.GridFSBucket;
  4. import com.mongodb.client.gridfs.GridFSBuckets;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8.  
  9. /**
  10. * @Description MongoDB配置类
  11. */
  12. @Configuration
  13. public class MongoConfig {
  14. /**
  15. * 数据库配置信息
  16. */
  17. @Value("${spring.data.mongodb.database}")
  18. private String db;
  19.  
  20. /**
  21. * GridFSBucket用于打开下载流
  22. * @param mongoClient
  23. * @return
  24. */
  25. @Bean
  26. public GridFSBucket getGridFSBucket(MongoClient mongoClient){
  27. MongoDatabase mongoDatabase = mongoClient.getDatabase(db);
  28. return GridFSBuckets.create(mongoDatabase);
  29. }
  30. }

FileUploadController.java

  1. import com.coisini.mongodb.model.ResponseMessage;
  2. import com.coisini.mongodb.service.FileUploadService;
  3. import com.coisini.mongodb.vo.FileExportVo;
  4. import lombok.extern.slf4j.Slf4j;
  5. import org.springframework.http.HttpHeaders;
  6. import org.springframework.http.HttpStatus;
  7. import org.springframework.http.ResponseEntity;
  8. import org.springframework.web.bind.annotation.*;
  9. import org.springframework.web.multipart.MultipartFile;
  10. import javax.annotation.Resource;
  11. import java.util.List;
  12. import java.util.Objects;
  13. /**
  14. * @Description 文件上传接口
  15. */
  16. @Slf4j
  17. @RestController
  18. @RequestMapping("/file")
  19. public class FileUploadController {
  20. /**
  21. * 文件上传实现类
  22. */
  23. @Resource(name="${fileUploadService.impl}")
  24. private FileUploadService fileUploadService;
  25. * 文件上传
  26. * @param file
  27. * @return
  28. @PostMapping("/upload")
  29. public ResponseMessage<?> uploadFile(@RequestParam(value = "file") MultipartFile file) {
  30. try {
  31. return ResponseMessage.ok("上传成功", fileUploadService.uploadFile(file));
  32. } catch (Exception e) {
  33. log.error("文件上传失败:", e);
  34. return ResponseMessage.error(e.getMessage());
  35. }
  36. }
  37. * 多文件上传
  38. * @param files
  39. @PostMapping("/uploadFiles")
  40. public ResponseMessage<?> uploadFile(@RequestParam(value = "files") List<MultipartFile> files) {
  41. return ResponseMessage.ok("上传成功", fileUploadService.uploadFiles(files));
  42. * 文件下载
  43. * @param fileId
  44. @GetMapping("/download/{fileId}")
  45. public ResponseEntity<Object> fileDownload(@PathVariable(name = "fileId") String fileId) {
  46. FileExportVo fileExportVo = fileUploadService.downloadFile(fileId);
  47. if (Objects.nonNull(fileExportVo)) {
  48. return ResponseEntity.ok()
  49. .header(HttpHeaders.CONTENT_DISPOSITION, "fileName=\"" + fileExportVo.getFileName() + "\"")
  50. .header(HttpHeaders.CONTENT_TYPE, fileExportVo.getContentType())
  51. .header(HttpHeaders.CONTENT_LENGTH, fileExportVo.getFileSize() + "").header("Connection", "close")
  52. .body(fileExportVo.getData());
  53. } else {
  54. return ResponseEntity.status(HttpStatus.NOT_FOUND).body("file does not exist");
  55. * 文件删除
  56. @DeleteMapping("/remove/{fileId}")
  57. public ResponseMessage<?> removeFile(@PathVariable(name = "fileId") String fileId) {
  58. fileUploadService.removeFile(fileId);
  59. return ResponseMessage.ok("删除成功");
  60. }

FileUploadService.java

  1. import com.coisini.mongodb.vo.FileExportVo;
  2. import org.springframework.web.multipart.MultipartFile;
  3. import java.util.List;
  4. /**
  5. * @Description 文件上传接口
  6. */
  7. public interface FileUploadService {
  8. /**
  9. * 文件上传
  10. * @param file
  11. * @return
  12. */
  13. FileExportVo uploadFile(MultipartFile file) throws Exception;
  14. /**
  15. * 多文件上传
  16. * @param files
  17. * @return
  18. */
  19. List<FileExportVo> uploadFiles(List<MultipartFile> files);
  20. /**
  21. * 文件下载
  22. * @param fileId
  23. * @return
  24. */
  25. FileExportVo downloadFile(String fileId);
  26. /**
  27. * 文件删除
  28. * @param fileId
  29. */
  30. void removeFile(String fileId);
  31. }

FileMongoServiceImpl.java

  1. import cn.hutool.core.io.IoUtil;
  2. import cn.hutool.core.util.IdUtil;
  3. import com.coisini.mongodb.model.MongoFile;
  4. import com.coisini.mongodb.repository.MongoFileRepository;
  5. import com.coisini.mongodb.service.FileUploadService;
  6. import com.coisini.mongodb.util.MD5Util;
  7. import com.coisini.mongodb.vo.FileExportVo;
  8. import com.mongodb.client.gridfs.GridFSBucket;
  9. import com.mongodb.client.gridfs.GridFSDownloadStream;
  10. import com.mongodb.client.gridfs.model.GridFSFile;
  11. import lombok.RequiredArgsConstructor;
  12. import lombok.extern.slf4j.Slf4j;
  13. import org.bson.types.Binary;
  14. import org.springframework.beans.factory.annotation.Autowired;
  15. import org.springframework.data.mongodb.core.MongoTemplate;
  16. import org.springframework.data.mongodb.core.query.Criteria;
  17. import org.springframework.data.mongodb.core.query.Query;
  18. import org.springframework.data.mongodb.gridfs.GridFsResource;
  19. import org.springframework.data.mongodb.gridfs.GridFsTemplate;
  20. import org.springframework.stereotype.Service;
  21. import org.springframework.web.multipart.MultipartFile;
  22. import java.io.IOException;
  23. import java.io.InputStream;
  24. import java.util.Date;
  25. import java.util.List;
  26. import java.util.Objects;
  27. import java.util.Optional;
  28. import java.util.stream.Collectors;
  29. /**
  30. * @Description MongoDB文件上传实现类
  31. */
  32. @Slf4j
  33. @Service("fileMongoServiceImpl")
  34. @RequiredArgsConstructor(onConstructor = @__(@Autowired))
  35. public class FileMongoServiceImpl implements FileUploadService {
  36. private final MongoFileRepository mongoFileRepository;
  37. private final MongoTemplate mongoTemplate;
  38. private final GridFsTemplate gridFsTemplate;
  39. private final GridFSBucket gridFSBucket;
  40. /**
  41. * 多文件上传
  42. * @param files
  43. * @return
  44. */
  45. @Override
  46. public List<FileExportVo> uploadFiles(List<MultipartFile> files) {
  47. return files.stream().map(file -> {
  48. try {
  49. return this.uploadFile(file);
  50. } catch (Exception e) {
  51. log.error("文件上传失败", e);
  52. return null;
  53. }
  54. }).filter(Objects::nonNull).collect(Collectors.toList());
  55. }
  56. /**
  57. * 文件上传
  58. * @param file
  59. * @return
  60. * @throws Exception
  61. */
  62. @Override
  63. public FileExportVo uploadFile(MultipartFile file) throws Exception {
  64. if (file.getSize() > 16777216) {
  65. return this.saveGridFsFile(file);
  66. } else {
  67. return this.saveBinaryFile(file);
  68. }
  69. }
  70. /**
  71. * 文件下载
  72. * @param fileId
  73. * @return
  74. */
  75. @Override
  76. public FileExportVo downloadFile(String fileId) {
  77. Optional<MongoFile> option = this.getBinaryFileById(fileId);
  78. if (option.isPresent()) {
  79. MongoFile mongoFile = option.get();
  80. if(Objects.isNull(mongoFile.getContent())){
  81. option = this.getGridFsFileById(fileId);
  82. }
  83. }
  84. return option.map(FileExportVo::new).orElse(null);
  85. }
  86. /**
  87. * 文件删除
  88. * @param fileId
  89. */
  90. @Override
  91. public void removeFile(String fileId) {
  92. Optional<MongoFile> option = this.getBinaryFileById(fileId);
  93. if (option.isPresent()) {
  94. if (Objects.nonNull(option.get().getGridFsId())) {
  95. this.removeGridFsFile(fileId);
  96. } else {
  97. this.removeBinaryFile(fileId);
  98. }
  99. }
  100. }
  101. /**
  102. * 删除Binary文件
  103. * @param fileId
  104. */
  105. public void removeBinaryFile(String fileId) {
  106. mongoFileRepository.deleteById(fileId);
  107. }
  108. /**
  109. * 删除GridFs文件
  110. * @param fileId
  111. */
  112. public void removeGridFsFile(String fileId) {
  113. // TODO 根据id查询文件
  114. MongoFile mongoFile = mongoTemplate.findById(fileId, MongoFile.class );
  115. if(Objects.nonNull(mongoFile)){
  116. // TODO 根据文件ID删除fs.files和fs.chunks中的记录
  117. Query deleteFileQuery = new Query().addCriteria(Criteria.where("filename").is(mongoFile.getGridFsId()));
  118. gridFsTemplate.delete(deleteFileQuery);
  119. // TODO 删除集合mongoFile中的数据
  120. Query deleteQuery = new Query(Criteria.where("id").is(fileId));
  121. mongoTemplate.remove(deleteQuery, MongoFile.class);
  122. }
  123. }
  124. /**
  125. * 保存Binary文件(小文件)
  126. * @param file
  127. * @return
  128. * @throws Exception
  129. */
  130. public FileExportVo saveBinaryFile(MultipartFile file) throws Exception {
  131. String suffix = getFileSuffix(file);
  132. MongoFile mongoFile = mongoFileRepository.save(
  133. MongoFile.builder()
  134. .fileName(file.getOriginalFilename())
  135. .fileSize(file.getSize())
  136. .content(new Binary(file.getBytes()))
  137. .contentType(file.getContentType())
  138. .uploadDate(new Date())
  139. .suffix(suffix)
  140. .md5(MD5Util.getMD5(file.getInputStream()))
  141. .build()
  142. );
  143. return new FileExportVo(mongoFile);
  144. }
  145. /**
  146. * 保存GridFs文件(大文件)
  147. * @param file
  148. * @return
  149. * @throws Exception
  150. */
  151. public FileExportVo saveGridFsFile(MultipartFile file) throws Exception {
  152. String suffix = getFileSuffix(file);
  153. String gridFsId = this.storeFileToGridFS(file.getInputStream(), file.getContentType());
  154. MongoFile mongoFile = mongoTemplate.save(
  155. MongoFile.builder()
  156. .fileName(file.getOriginalFilename())
  157. .fileSize(file.getSize())
  158. .contentType(file.getContentType())
  159. .uploadDate(new Date())
  160. .suffix(suffix)
  161. .md5(MD5Util.getMD5(file.getInputStream()))
  162. .gridFsId(gridFsId)
  163. .build()
  164. );
  165. return new FileExportVo(mongoFile);
  166. }
  167. /**
  168. * 上传文件到Mongodb的GridFs中
  169. * @param in
  170. * @param contentType
  171. * @return
  172. */
  173. public String storeFileToGridFS(InputStream in, String contentType){
  174. String gridFsId = IdUtil.simpleUUID();
  175. // TODO 将文件存储进GridFS中
  176. gridFsTemplate.store(in, gridFsId , contentType);
  177. return gridFsId;
  178. }
  179. /**
  180. * 获取Binary文件
  181. * @param id
  182. * @return
  183. */
  184. public Optional<MongoFile> getBinaryFileById(String id) {
  185. return mongoFileRepository.findById(id);
  186. }
  187. /**
  188. * 获取Grid文件
  189. * @param id
  190. * @return
  191. */
  192. public Optional<MongoFile> getGridFsFileById(String id){
  193. MongoFile mongoFile = mongoTemplate.findById(id , MongoFile.class );
  194. if(Objects.nonNull(mongoFile)){
  195. Query gridQuery = new Query().addCriteria(Criteria.where("filename").is(mongoFile.getGridFsId()));
  196. try {
  197. // TODO 根据id查询文件
  198. GridFSFile fsFile = gridFsTemplate.findOne(gridQuery);
  199. // TODO 打开流下载对象
  200. GridFSDownloadStream in = gridFSBucket.openDownloadStream(fsFile.getObjectId());
  201. if(in.getGridFSFile().getLength() > 0){
  202. // TODO 获取流对象
  203. GridFsResource resource = new GridFsResource(fsFile, in);
  204. // TODO 获取数据
  205. mongoFile.setContent(new Binary(IoUtil.readBytes(resource.getInputStream())));
  206. return Optional.of(mongoFile);
  207. }else {
  208. return Optional.empty();
  209. }
  210. }catch (IOException e){
  211. log.error("获取MongoDB大文件失败", e);
  212. }
  213. }
  214. return Optional.empty();
  215. }
  216. /**
  217. * 获取文件后缀
  218. * @param file
  219. * @return
  220. */
  221. private String getFileSuffix(MultipartFile file) {
  222. String suffix = "";
  223. if (Objects.requireNonNull(file.getOriginalFilename()).contains(".")) {
  224. suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
  225. }
  226. return suffix;
  227. }
  228. }

MongoFileRepository.java

  1. import com.coisini.mongodb.model.MongoFile;
  2. import org.springframework.data.mongodb.repository.MongoRepository;
  3.  
  4. /**
  5. * @Description MongoDB文件仓储
  6. */
  7. public interface MongoFileRepository extends MongoRepository<MongoFile, String> {
  8.  
  9. }

MongoFile.java

  1. import lombok.Builder;
  2. import lombok.Data;
  3. import org.bson.types.Binary;
  4. import org.springframework.data.annotation.Id;
  5. import org.springframework.data.mongodb.core.mapping.Document;
  6. import java.util.Date;
  7.  
  8. /**
  9. * @Description MongoDB文件实体
  10. */
  11. @Document
  12. @Builder
  13. @Data
  14. public class MongoFile {
  15.  
  16. /**
  17. * 主键
  18. */
  19. @Id
  20. public String id;
  21.  
  22. /**
  23. * 文件名称
  24. */
  25. public String fileName;
  26.  
  27. /**
  28. * 文件大小
  29. */
  30. public long fileSize;
  31.  
  32. /**
  33. * 上传时间
  34. */
  35. public Date uploadDate;
  36.  
  37. /**
  38. * MD5值
  39. */
  40. public String md5;
  41.  
  42. /**
  43. * 文件内容
  44. */
  45. private Binary content;
  46.  
  47. /**
  48. * 文件类型
  49. */
  50. public String contentType;
  51.  
  52. /**
  53. * 文件后缀名
  54. */
  55. public String suffix;
  56.  
  57. /**
  58. * 文件描述
  59. */
  60. public String description;
  61.  
  62. /**
  63. * 大文件管理GridFS的ID
  64. */
  65. private String gridFsId;
  66.  
  67. }

ResponseMessage.java

  1. /**
  2. * @Description 统一消息
  3. */
  4. public class ResponseMessage<T> {
  5.  
  6. private String status;
  7. private String message;
  8. private T data;
  9.  
  10. // 省略
  11.  
  12. }

FileExportVo.java

  1. import java.util.Objects;
  2.  
  3. /**
  4. * @Description 统一文件下载vo
  5. */
  6. @Data
  7. public class FileExportVo {
  8.  
  9. private String fileId;
  10.  
  11. private String fileName;
  12.  
  13. private String contentType;
  14.  
  15. private String suffix;
  16.  
  17. private long fileSize;
  18.  
  19. @JsonIgnore
  20. private byte[] data;
  21.  
  22. public FileExportVo(MongoFile mongoFile) {
  23. BeanUtil.copyProperties(mongoFile, this);
  24. if (Objects.nonNull(mongoFile.getContent())) {
  25. this.data = mongoFile.getContent().getData();
  26. }
  27. this.fileId = mongoFile.getId();
  28. }
  29.  
  30. }

MD5Util.java

  1. import java.io.IOException;
  2. import java.io.InputStream;
  3. import java.security.MessageDigest;
  4. import java.security.NoSuchAlgorithmException;
  5.  
  6. /**
  7. * @Description MD5工具类
  8. */
  9. public class MD5Util {
  10. /**
  11. * 获取该输入流的MD5值
  12. */
  13. public static String getMD5(InputStream is) throws NoSuchAlgorithmException, IOException {
  14. StringBuffer md5 = new StringBuffer();
  15. MessageDigest md = MessageDigest.getInstance("MD5");
  16. byte[] dataBytes = new byte[1024];
  17.  
  18. int nread = 0;
  19. while ((nread = is.read(dataBytes)) != -1) {
  20. md.update(dataBytes, 0, nread);
  21. };
  22. byte[] mdbytes = md.digest();
  23.  
  24. // convert the byte to hex format
  25. for (int i = 0; i < mdbytes.length; i++) {
  26. md5.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
  27. }
  28. return md5.toString();
  29. }
  30. }

测试

文件上传

在这里插入图片描述

多文件上传

在这里插入图片描述

文件下载

在这里插入图片描述

文件删除

在这里插入图片描述

源码

GitHubhttps://github.com/Maggieq8324/java-learn-demo/tree/master/springboot-mongodb-file

Giteehttps://gitee.com/maggieq8324/java-learn-demo/tree/master/springboot-mongodb-file

到此这篇关于SpringBoot 集成MongoDB实现文件上传的文章就介绍到这了,更多相关SpringBoot 集成MongoDB文件上传内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号