前言
- 记录下
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
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <!-- mongodb -->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-mongodb</artifactId>
- </dependency>
- <!-- lombok -->
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <!-- hutool -->
- <dependency>
- <groupId>cn.hutool</groupId>
- <artifactId>hutool-all</artifactId>
- <version>4.5.1</version>
- </dependency>
application.yml
- server:
- port: 31091
-
- spring:
- servlet:
- multipart:
- max-file-size: 100MB
- data:
- mongodb:
- host: 127.0.0.1
- port: 27017
- database: admin
- username: root
- password: sunday
-
- fileUploadService:
- impl: fileMongoServiceImpl
MongoConfig.java
- import com.mongodb.client.MongoClient;
- import com.mongodb.client.MongoDatabase;
- import com.mongodb.client.gridfs.GridFSBucket;
- import com.mongodb.client.gridfs.GridFSBuckets;
- import org.springframework.beans.factory.annotation.Value;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
-
- /**
- * @Description MongoDB配置类
- */
- @Configuration
- public class MongoConfig {
- /**
- * 数据库配置信息
- */
- @Value("${spring.data.mongodb.database}")
- private String db;
-
- /**
- * GridFSBucket用于打开下载流
- * @param mongoClient
- * @return
- */
- @Bean
- public GridFSBucket getGridFSBucket(MongoClient mongoClient){
- MongoDatabase mongoDatabase = mongoClient.getDatabase(db);
- return GridFSBuckets.create(mongoDatabase);
- }
- }
FileUploadController.java
- import com.coisini.mongodb.model.ResponseMessage;
- import com.coisini.mongodb.service.FileUploadService;
- import com.coisini.mongodb.vo.FileExportVo;
- import lombok.extern.slf4j.Slf4j;
- import org.springframework.http.HttpHeaders;
- import org.springframework.http.HttpStatus;
- import org.springframework.http.ResponseEntity;
- import org.springframework.web.bind.annotation.*;
- import org.springframework.web.multipart.MultipartFile;
- import javax.annotation.Resource;
- import java.util.List;
- import java.util.Objects;
- /**
- * @Description 文件上传接口
- */
- @Slf4j
- @RestController
- @RequestMapping("/file")
- public class FileUploadController {
- /**
- * 文件上传实现类
- */
- @Resource(name="${fileUploadService.impl}")
- private FileUploadService fileUploadService;
- * 文件上传
- * @param file
- * @return
- @PostMapping("/upload")
- public ResponseMessage<?> uploadFile(@RequestParam(value = "file") MultipartFile file) {
- try {
- return ResponseMessage.ok("上传成功", fileUploadService.uploadFile(file));
- } catch (Exception e) {
- log.error("文件上传失败:", e);
- return ResponseMessage.error(e.getMessage());
- }
- }
- * 多文件上传
- * @param files
- @PostMapping("/uploadFiles")
- public ResponseMessage<?> uploadFile(@RequestParam(value = "files") List<MultipartFile> files) {
- return ResponseMessage.ok("上传成功", fileUploadService.uploadFiles(files));
- * 文件下载
- * @param fileId
- @GetMapping("/download/{fileId}")
- public ResponseEntity<Object> fileDownload(@PathVariable(name = "fileId") String fileId) {
- FileExportVo fileExportVo = fileUploadService.downloadFile(fileId);
- if (Objects.nonNull(fileExportVo)) {
- return ResponseEntity.ok()
- .header(HttpHeaders.CONTENT_DISPOSITION, "fileName=\"" + fileExportVo.getFileName() + "\"")
- .header(HttpHeaders.CONTENT_TYPE, fileExportVo.getContentType())
- .header(HttpHeaders.CONTENT_LENGTH, fileExportVo.getFileSize() + "").header("Connection", "close")
- .body(fileExportVo.getData());
- } else {
- return ResponseEntity.status(HttpStatus.NOT_FOUND).body("file does not exist");
- * 文件删除
- @DeleteMapping("/remove/{fileId}")
- public ResponseMessage<?> removeFile(@PathVariable(name = "fileId") String fileId) {
- fileUploadService.removeFile(fileId);
- return ResponseMessage.ok("删除成功");
- }
FileUploadService.java
- import com.coisini.mongodb.vo.FileExportVo;
- import org.springframework.web.multipart.MultipartFile;
- import java.util.List;
- /**
- * @Description 文件上传接口
- */
- public interface FileUploadService {
- /**
- * 文件上传
- * @param file
- * @return
- */
- FileExportVo uploadFile(MultipartFile file) throws Exception;
- /**
- * 多文件上传
- * @param files
- * @return
- */
- List<FileExportVo> uploadFiles(List<MultipartFile> files);
- /**
- * 文件下载
- * @param fileId
- * @return
- */
- FileExportVo downloadFile(String fileId);
- /**
- * 文件删除
- * @param fileId
- */
- void removeFile(String fileId);
- }
FileMongoServiceImpl.java
- 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;
- /**
- * @Description MongoDB文件上传实现类
- */
- @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;
- /**
- * 多文件上传
- * @param files
- * @return
- */
- @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());
- }
- /**
- * 文件上传
- * @param file
- * @return
- * @throws Exception
- */
- @Override
- public FileExportVo uploadFile(MultipartFile file) throws Exception {
- if (file.getSize() > 16777216) {
- return this.saveGridFsFile(file);
- } else {
- return this.saveBinaryFile(file);
- }
- }
- /**
- * 文件下载
- * @param fileId
- * @return
- */
- @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);
- }
- /**
- * 文件删除
- * @param fileId
- */
- @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);
- }
- }
- }
- /**
- * 删除Binary文件
- * @param fileId
- */
- public void removeBinaryFile(String fileId) {
- mongoFileRepository.deleteById(fileId);
- }
- /**
- * 删除GridFs文件
- * @param 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);
- }
- }
- /**
- * 保存Binary文件(小文件)
- * @param file
- * @return
- * @throws Exception
- */
- 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);
- }
- /**
- * 保存GridFs文件(大文件)
- * @param file
- * @return
- * @throws Exception
- */
- 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);
- }
- /**
- * 上传文件到Mongodb的GridFs中
- * @param in
- * @param contentType
- * @return
- */
- public String storeFileToGridFS(InputStream in, String contentType){
- String gridFsId = IdUtil.simpleUUID();
- // TODO 将文件存储进GridFS中
- gridFsTemplate.store(in, gridFsId , contentType);
- return gridFsId;
- }
- /**
- * 获取Binary文件
- * @param id
- * @return
- */
- public Optional<MongoFile> getBinaryFileById(String id) {
- return mongoFileRepository.findById(id);
- }
- /**
- * 获取Grid文件
- * @param id
- * @return
- */
- 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();
- }
- /**
- * 获取文件后缀
- * @param file
- * @return
- */
- private String getFileSuffix(MultipartFile file) {
- String suffix = "";
- if (Objects.requireNonNull(file.getOriginalFilename()).contains(".")) {
- suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));
- }
- return suffix;
- }
- }
MongoFileRepository.java
- import com.coisini.mongodb.model.MongoFile;
- import org.springframework.data.mongodb.repository.MongoRepository;
-
- /**
- * @Description MongoDB文件仓储
- */
- public interface MongoFileRepository extends MongoRepository<MongoFile, String> {
-
- }
MongoFile.java
- import lombok.Builder;
- import lombok.Data;
- import org.bson.types.Binary;
- import org.springframework.data.annotation.Id;
- import org.springframework.data.mongodb.core.mapping.Document;
- import java.util.Date;
-
- /**
- * @Description MongoDB文件实体
- */
- @Document
- @Builder
- @Data
- public class MongoFile {
-
- /**
- * 主键
- */
- @Id
- public String id;
-
- /**
- * 文件名称
- */
- public String fileName;
-
- /**
- * 文件大小
- */
- public long fileSize;
-
- /**
- * 上传时间
- */
- public Date uploadDate;
-
- /**
- * MD5值
- */
- public String md5;
-
- /**
- * 文件内容
- */
- private Binary content;
-
- /**
- * 文件类型
- */
- public String contentType;
-
- /**
- * 文件后缀名
- */
- public String suffix;
-
- /**
- * 文件描述
- */
- public String description;
-
- /**
- * 大文件管理GridFS的ID
- */
- private String gridFsId;
-
- }
ResponseMessage.java
- /**
- * @Description 统一消息
- */
- public class ResponseMessage<T> {
-
- private String status;
- private String message;
- private T data;
-
- // 省略
-
- }
FileExportVo.java
- import java.util.Objects;
-
- /**
- * @Description 统一文件下载vo
- */
- @Data
- public class FileExportVo {
-
- private String fileId;
-
- private String fileName;
-
- private String contentType;
-
- private String suffix;
-
- private long fileSize;
-
- @JsonIgnore
- private byte[] data;
-
- public FileExportVo(MongoFile mongoFile) {
- BeanUtil.copyProperties(mongoFile, this);
- if (Objects.nonNull(mongoFile.getContent())) {
- this.data = mongoFile.getContent().getData();
- }
- this.fileId = mongoFile.getId();
- }
-
- }
MD5Util.java
- import java.io.IOException;
- import java.io.InputStream;
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
-
- /**
- * @Description MD5工具类
- */
- public class MD5Util {
- /**
- * 获取该输入流的MD5值
- */
- public static String getMD5(InputStream is) throws NoSuchAlgorithmException, IOException {
- StringBuffer md5 = new StringBuffer();
- MessageDigest md = MessageDigest.getInstance("MD5");
- byte[] dataBytes = new byte[1024];
-
- int nread = 0;
- while ((nread = is.read(dataBytes)) != -1) {
- md.update(dataBytes, 0, nread);
- };
- byte[] mdbytes = md.digest();
-
- // convert the byte to hex format
- for (int i = 0; i < mdbytes.length; i++) {
- md5.append(Integer.toString((mdbytes[i] & 0xff) + 0x100, 16).substring(1));
- }
- return md5.toString();
- }
- }
测试
文件上传

多文件上传

文件下载

文件删除

源码
GitHub
:https://github.com/Maggieq8324/java-learn-demo/tree/master/springboot-mongodb-file
Gitee
:https://gitee.com/maggieq8324/java-learn-demo/tree/master/springboot-mongodb-file
到此这篇关于SpringBoot 集成MongoDB实现文件上传的文章就介绍到这了,更多相关SpringBoot 集成MongoDB文件上传内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!