一. 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查看结果