赞
踩
MongoDB GridFS支持大文件存储:
GridFS用于存储和恢复那些超过16M(BSON文件限制)的文件(如:图片、音频、视频等);
GridFS 也是文件存储的一种方式,但是它是存储在MonoDB的集合中;
GridFS 可以更好的存储大于16M的文件;
GridFS 会将大文件对象分割成多个小的chunk(文件片段),一般为256k/个,每个chunk将作为MongoDB的一个文档(document)被存储在chunks集合中;
每个文件的实际内容被存在chunks(二进制数据)中,和文件有关的meta数据(filename,content_type,还有用户自定义的属性)将会被存在files集合中。
spring-boot-starter-data-mongodb 基于GridFS实现文件的上传下载
application配置文件
- server:
- port: 9001
- spring:
- data:
- mongodb:
- uri: mongodb://root:123456@127.0.0.1:27017/fileInfo?readPreference=secondary&authSource=admin
- jackson:
- default-property-inclusion: non_null
- servlet:
- multipart:
- max-file-size: 10MB #单个文件上传大小
- max-request-size: 100MB #单次请求文件上传大小
- http:
- encoding:
- charset: UTF-8
自定义实体类记录上传文件的相关信息
- @Data
- @AllArgsConstructor
- @NoArgsConstructor
- @Document(collection = "tbl_data_record")
- public class FileMetaDomain implements Serializable {
-
- private static final long serialVersionUID = 7733095063283270367L;
-
- @Id
- private String id;
-
- /* 文件信息存储在数据库中的uuid */ private List<Object> fileIds;
-
- /* 源文件名 */ private String fileName;
-
- /* 文件类型 */ private String contentType;
-
- /* 文件大小 */ private long size;
-
- /* 更新日期 */ private LocalDate updateTime = LocalDate.now();
-
- /* 创建日期 */ private LocalDate createTime = LocalDate.now();
-
- public FileMetaDomain(String id, String fileName, String contentType, long size){
- this.id = id; this.fileName = fileName;
- this.contentType = contentType;this.size = size;
- }
- }

Dao层接口
- @Repository
- public interface GridFSRepository extends MongoRepository<FileMetaDomain,String> {
-
- @Query("{'fileName': ?0}")
- FileMetaDomain findByFileName(String fileName);
- }
Service逻辑处理
- public interface GridFsService {
-
- String saveFile(MultipartFile file) throws IOException;
-
- void downLoad(HttpServletResponse response, String fileName);
- }
实现类
- @Slf4j
- @Service
- public class GridFSServiceImpl implements GridFsService {
-
- private final MongoTemplate mongoTemplate;
-
- private final GridFSRepository repository;
-
- private final GridFsTemplate gridFsTemplate;
-
- @Autowired
- public GridFSServiceImpl(GridFSRepository repository, MongoTemplate mongoTemplate, GridFsTemplate gridFsTemplate) {
- this.repository = repository;
- this.mongoTemplate = mongoTemplate;
- this.gridFsTemplate = gridFsTemplate;
- }
-
- @Override
- public String saveFile(MultipartFile file) throws IOException {
- //源文件名
- String originalFilename = file.getOriginalFilename();
- //文件类型
- String contentType = file.getContentType();
- //文件大小
- long size = file.getSize();
- MongoDatabase db = mongoTemplate.getDb();
- GridFSBucket gridFSBucket = GridFSBuckets.create(db);
- ObjectId objectId = gridFSBucket.uploadFromStream(originalFilename, file.getInputStream());
- FileMetaDomain fileMetaDomain = new FileMetaDomain(objectId.toString(),originalFilename,contentType,size);
- FileMetaDomain fileMeta = repository.save(fileMetaDomain);
- return fileMeta.getId();
- }
-
- @Override
- public void downLoad(HttpServletResponse response, String fileName){
- FileMetaDomain fileMetaDomain = repository.findByFileName(fileName);
- Assert.notNull(fileMetaDomain,"当前下载的文件未上传到服务器");
- Query query = new Query();
- query.addCriteria(Criteria.where("filename").is(fileName));
- GridFSFile file = gridFsTemplate.findOne(query);
- MongoDatabase db = mongoTemplate.getDb();
- try {
- //文件名转码,支持中文文件名下载
- fileName = URLEncoder.encode(fileName,"UTF-8");
- response.setContentType("application/vnd.ms-excel;charset=utf-8");
- response.setHeader("Content-Disposition","attachment;filename="+fileName);
- ServletOutputStream outputStream = response.getOutputStream();
- GridFSBuckets.create(db).downloadToStream(file.getObjectId(),outputStream);
- outputStream.flush();
- outputStream.close();
- }catch (Exception e){
- e.printStackTrace();
- }
- }
- }

文件上传下载接口
- @Slf4j
- @RestController
- @RequestMapping("/file")
- public class GridFSController {
-
- private final GridFsService service;
-
- @Autowired
- public GridFSController(GridFsService service) {
- this.service = service;
- }
-
- @PostMapping("/upload")
- @ResponseBody
- public ResponseEntity<String> upload(@RequestParam("file") MultipartFile file){
- try {
- if(ObjectUtils.isEmpty(file)){
- return ResponseEntity.ok().body("上传文件不能为空");
- }else {
- return ResponseEntity.ok().body(service.saveFile(file));
- }
- }catch (Exception e){
- log.error("[Upload Failed]",e);
- return ResponseEntity.badRequest().body(e.getMessage());
- }
- }
-
- @GetMapping("/download")
- public ResponseEntity<String> download(HttpServletResponse response, @RequestParam("fileName")String fileName){
- try {
- service.downLoad(response,fileName);
- return ResponseEntity.ok().body("SUCCESS");
- }catch (Exception e){
- log.error("[Download Failed]",e.getMessage());
- return ResponseEntity.badRequest().body(e.getMessage());
- }
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。