<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
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檔案上傳內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45