SpringBoot 集成MongoDB实现文件上传功能

2023-12-04 0 912
目录
  • 前言
  • 环境
  • 代码实现
  • 测试
  • 源码

前言

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

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

环境

SpringBoot – 2.5.12MongoDB – 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();
}
}

测试

文件上传

SpringBoot 集成MongoDB实现文件上传功能

多文件上传

SpringBoot 集成MongoDB实现文件上传功能

文件下载

SpringBoot 集成MongoDB实现文件上传功能

文件删除

SpringBoot 集成MongoDB实现文件上传功能

源码

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文件上传内容请搜索悠久资源以前的文章或继续浏览下面的相关文章希望大家以后多多支持悠久资源!

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 MongoDB SpringBoot 集成MongoDB实现文件上传功能 https://www.u-9.cn/database/mongodb/69427.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务