一. GridFS介紹:
mongodb數據庫支持文件存儲,GridFS是MongoDB提供的用於持久化存儲文件的模塊.
GridFS工作原理是:
在GridFS存儲文件是將文件分塊存儲,文件會按照256KB的大小分割成多個塊進行存儲,GridFS使用兩個集合(collection)存儲文件,一個集合是chunks, 用於存儲文件的二進制數據;一個集合files,用於存儲文件的元數據信息(文件名稱、塊大小、上傳時間等信息)。
從GridFS中讀取文件要對文件的各各塊進行組裝、合併。
二. 需求說明
使用GridFS實現mongodb文件存儲
三. 實現方案
spring data mongodb提供了操作gridFS的方法,通過@Autowired注入GridFsTemplate和GridFsBucket並調用其方法可以實現mongodb文件存儲,將文件實際數據保存到fs.chunks集合並將文件信息保存到fs.files集合中.
四. 實現步驟
1.cms項目在此之前已集合spring data mongodb
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
配置文件
spring:
application:
name: sc-multipl-manage-cms # 服務名稱
## 配置數據庫連接
data:
## mongoDB
mongodb:
uri: mongodb://localhost:27017
database: xc_cms
- 文件操作實體類
public class CmsFile {
private String fileId;
private String fileName;
private String md5;
}
- 編寫Service,實現文件上傳下載和刪除功能
@Service
public class CmsFileServiceImpl implements CmsFileService {
@Autowired
GridFsTemplate gridFsTemplate;
@Autowired
GridFSBucket gridFSBucket;
@Override
public CmsFile uploadFileToMongo(MultipartFile file) {
//獲取上傳文件名,包含後綴
String originalFilename = file.getOriginalFilename();
//獲取後綴
String substring = originalFilename.substring(originalFilename.lastIndexOf("."));
//使用uuid加.後綴的方式生成文件名
String dFileName = UUID.randomUUID() + substring;
//獲取出入流
InputStream inputStream = null;
ObjectId objectId = null;
try {
inputStream = file.getInputStream();
objectId = gridFsTemplate.store(inputStream, dFileName);
} catch (IOException e) {
e.printStackTrace();
}
if (objectId == null) {
ExceptionCast.cast(CmsCode.CMS_UPLOADFILE_FAIL);
}
CmsFile cmsFile = new CmsFile();
cmsFile.setFileId(objectId.toString());
cmsFile.setFileName(dFileName);
return cmsFile;
}
@Override
public String getFileStringByFileId(String fileId) {
//根據id查詢文件
GridFSFile gridFSFile = gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(fileId)));
if (gridFSFile == null){
ExceptionCast.cast(CmsCode.CMS_FILE_NOTEXISTS);
}
//打開下載流對象
GridFSDownloadStream downloadStream =
gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
//創建gridFsResource,用於獲取流對象
GridFsResource gridFsResource = new GridFsResource(gridFSFile, downloadStream);
String fileString = null;
try {
//獲取流中的數據
fileString = IOUtils.toString(gridFsResource.getInputStream(), "utf-8");
} catch (IOException e) {
e.printStackTrace();
}
return fileString;
}
@Override
public boolean deleteFileByFileId(String fileId) {
if (StringUtils.isNotBlank(fileId)){
//根據文件id刪除fs.files和fs.chunks中的記錄
gridFsTemplate.delete(Query.query(Criteria.where("_id").is(fileId)));
}
return true;
}
}
4.編寫controller類
@RestController
@RequestMapping("/cms/file")
public class CmsFileController implements CmsFileControllerApi {
@Autowired
CmsFileService cmsFileService;
@Override
@RequestMapping("uploadFileToMongo")
public QueryListResult<CmsFile> uploadFileToMongo(@RequestParam("file") MultipartFile file) {
CmsFile cmsFile = cmsFileService.uploadFileToMongo(file);
ListResult<CmsFile> listResult = new ListResult<>();
listResult.setTotal(1);
List<CmsFile> list = new ArrayList<>();
list.add(cmsFile);
listResult.setList(list);
return QueryListResult.returnSuccess(listResult);
}
@Override
@GetMapping("getFileStringByFileId/{fileId}")
public QueryOneResult<String> getFileStringByFileId(@PathVariable("fileId") String fileId) {
String fileString = cmsFileService.getFileStringByFileId(fileId);
OneResult<String> oneResult = new OneResult<>();
oneResult.setResult(fileString);
return QueryOneResult.returnSuccess(oneResult);
}
@Override
@GetMapping("deleteFileByFileId/{fileId}")
public ResponseResult deleteFileByFileId(@PathVariable("fileId") String fileId) {
boolean result = cmsFileService.deleteFileByFileId(fileId);
return result?ResponseResult.returnSuccess():ResponseResult.returnFail();
}
}
最後,測試,我用的是postman,並在fschunks和fs.files查看結果