Springboot使用Mongo数据库实现文件的上传下载预览等服务接口

MongoDB GridFS 简介

MongoDB GridFS是一个用于存储和检索大型文件的规范,它允许在MongoDB数据库中存储超过16MB的文件,如图片、音频、视频等。GridFS通过将文件分割成多个小的chunk(文件片段),每个chunk通常为255KB,并将这些chunk存储在MongoDB的集合中,从而解决了MongoDB对单个文档大小的限制。以下是GridFS的详细介绍:

GridFS的基本概念

  • 文件分割:GridFS将大型文件分割成多个chunk,每个chunk的大小默认为255KB,最后一个chunk的大小可能小于255KB,以适应文件的实际大小。
  • 存储结构:GridFS使用两个集合来存储文件:fs.filesfs.chunksfs.files集合存储文件的元数据,如文件名、文件类型、上传时间等;fs.chunks集合存储文件的二进制数据块。

Springboot使用Mongo数据库实现文件的上传下载预览等服务接口_第1张图片

GridFS的使用场景

  • 存储大型文件:对于超过16MB的文件,可以使用GridFS进行存储。
  • 文件的部分访问:可以只加载文件的部分内容,而不必将整个文件加载到内存中,这对于处理大文件非常有用。
  • 分布式文件系统:在多个系统和设施之间自动同步和部署文件及元数据。

如何使用GridFS

  • 安装MongoDB驱动程序:首先需要安装MongoDB的官方驱动程序。
  • 连接到MongoDB数据库:在应用程序中创建一个MongoDB数据库连接。
  • 创建GridFS存储:使用MongoDB的GridFS API创建一个GridFS存储对象。
  • 上传文件:使用GridFS的API将文件上传到数据库中。
  • 下载文件:使用GridFS的API从数据库中下载文件。

GridFS的优势

  • 灵活性:GridFS允许存储任意大小的文件,只要它们可以分割成多个chunk。
  • 性能:在某些情况下,存储大型文件在MongoDB数据库中可能比在系统级文件系统上更有效率。
  • 易用: 使用springboot整合GridFS非常简单容易上手。

代码教程

引入依赖

在pom.xml文件中添加mongo依赖

   <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-mongodbartifactId>
        dependency>

配置连接信息

在spring配置文件里,配置mongo数据库连接信息

spring:
  data:
    mongodb:
      database: ${MONGO_DATABASE:work_face_exam}
      uri: mongodb://${MONGO_USERNAME:glqxzh}:${MONGO_PASSWORD:123456789}@${MONGO_HOST:127.0.0.1}:27017

创建MongoDB GridFS 服务类

代码如下:


import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.client.gridfs.model.GridFSFile;
import lombok.AllArgsConstructor;
import org.bson.types.ObjectId;
import org.springblade.coalface.modules.file.vo.FileVO;
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.ArrayList;
import java.util.Date;
import java.util.List;

@Service
@AllArgsConstructor
public class MongoFileService {

    private final GridFsTemplate gridFsTemplate;

    public FileVO saveFile(MultipartFile file) throws IOException {
        FileVO filevo = new FileVO();
        // 新文件名
        String originalFilename = file.getOriginalFilename();
        filevo.setFileName(originalFilename);
        filevo.setFileSize(file.getSize());
        // 获得文件类型
        String contentType = file.getContentType();
        filevo.setType(contentType);
        // 将文件存储到mongodb中,mongodb将会返回这个文件的具体信息
        // 上传文件中我们也可以使用DBObject附加一些属性
        // 获得文件输入流
        InputStream ins = file.getInputStream();
        DBObject metadata = new BasicDBObject();
        ObjectId objectId = gridFsTemplate.store(ins, originalFilename, contentType, metadata);
        filevo.setId(objectId.toString());
        filevo.setUploadTime(new Date());
        filevo.setUrl("/files/" + objectId);
        return filevo;
    }
    public List<GridFSFile> list() {
        return  gridFsTemplate.find(new Query()).into(new ArrayList<>());
    }

    public void removeById(String fileId) {
        gridFsTemplate.delete(Query.query(Criteria.where("_id").is(fileId)));
    }

    public GridFSFile getById(String fileId) {
        return gridFsTemplate.findOne(new Query(Criteria.where("_id").is(fileId)));
    }

    public InputStream getStream(GridFSFile file) throws IOException {
        GridFsResource resource = gridFsTemplate.getResource(file);
        return resource.getInputStream();
    }
}

代码解读:

这段代码是一个用于处理MongoDB GridFS文件存储的服务类。下面是对这段代码的详细解读:

  1. 导入依赖
    导入了所需的依赖包,包括MongoDB的相关类、Spring Boot的相关类以及Lombok库。

  2. 服务类定义
    使用@Service注解标记该类为一个服务类,表示该类提供业务逻辑功能。同时使用@AllArgsConstructor注解来自动生成一个包含所有成员变量的构造函数。

  3. 成员变量
    private final GridFsTemplate gridFsTemplate;:这是一个GridFsTemplate对象,用于操作MongoDB的GridFS存储。

  4. saveFile方法
    该方法用于将上传的文件保存到MongoDB的GridFS中。首先创建一个FileVO对象,设置文件的基本信息(如文件名、文件大小、文件类型等)。然后获取文件的输入流,并创建一个DBObject对象用于存储文件的元数据。接着调用gridFsTemplate.store()方法将文件存储到MongoDB中,并返回一个ObjectId对象。最后设置FileVO对象的ID、上传时间和URL,并返回该对象。

  5. list方法
    该方法用于列出GridFS中的所有文件。通过调用gridFsTemplate.find()方法并传入一个空的Query对象来获取所有的GridFSFile对象,并将其转换为ArrayList返回。

  6. removeById方法
    该方法用于根据文件ID删除GridFS中的文件。通过调用gridFsTemplate.delete()方法并传入一个包含文件ID的Criteria对象来实现。

  7. getById方法
    该方法用于根据文件ID获取GridFS中的文件。通过调用gridFsTemplate.findOne()方法并传入一个包含文件ID的Criteria对象来实现。

  8. getStream方法
    该方法用于获取GridFS中文件的输入流。首先通过调用gridFsTemplate.getResource()方法获取一个GridFsResource对象,然后调用该对象的getInputStream()方法获取文件的输入流。

创建MongoDB GridFS API接口类

代码如下:



import com.mongodb.client.gridfs.model.GridFSFile;
import io.swagger.annotations.ApiOperation;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.bson.Document;
import org.springblade.coalface.modules.file.service.MongoFileService;
import org.springblade.coalface.modules.file.vo.FileVO;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.IoUtil;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.net.URLEncoder;

@Slf4j
@RestController
@RequestMapping("/")
@AllArgsConstructor
public class MongoFileController {
    private final MongoFileService mongoFileService;

    @PostMapping("file/upload")
    @ApiOperation(value = "文件上传")
    public R<FileVO> uploadFile(MultipartFile file) {
        try {
            return R.data(mongoFileService.saveFile(file));
        } catch (Exception e) {
            return R.fail(e.getMessage());
        }
    }

    @PostMapping("download")
    @ApiOperation(value = "文件仅下载")
    public void downloadFile(String fileId, HttpServletResponse response) {
        try {
            GridFSFile file = mongoFileService.getById(fileId);
            response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
            String encodedFileName = URLEncoder.encode(file.getFilename(), "UTF-8").replace("+", "%20");
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
                    "attachment; filename*=UTF-8''" + encodedFileName);
            IoUtil.copy(mongoFileService.getStream(file), response.getOutputStream());
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    @GetMapping("files/{fileId}")
    @ApiOperation(value = "文件预览下载")
    public void getFile(@PathVariable("fileId") String fileId, HttpServletResponse response) {
        try {
            GridFSFile file = mongoFileService.getById(fileId);
            Document doc=file.getMetadata();
            // 获取文件的MIME类型
            assert doc != null;
            String mimeType = doc.getString("_contentType");
            response.setContentType(mimeType);
            String encodedFileName = URLEncoder.encode(file.getFilename(), "UTF-8").replace("+", "%20");
            response.setHeader(HttpHeaders.CONTENT_DISPOSITION,
                    "inline; filename*=UTF-8''" + encodedFileName);
            IoUtil.copy(mongoFileService.getStream(file), response.getOutputStream());
        } catch (Exception e) {
            log.error(e.getMessage());
        }
    }

    @PostMapping("remove/{fileId}")
    @ApiOperation(value = "文件删除")
    public R<String> removeFile(@PathVariable("fileId") String fileId) {
        mongoFileService.removeById(fileId);
        return R.success();
    }



}

  • 该类中总共封装了三个接口,上传接口、仅下载接口、和文件预览接口
  • 文件预览接口能将浏览器可以显示文件,显示在浏览器上,不直接下载,例如图片、视频、pdf文件等可以直接在浏览器预览、其他不能再浏览器上显示的文件、如zip压缩包、exe安装程序、word/excel文件等则直接下载。

你可能感兴趣的:(技术交流,spring,boot,数据库,后端,mongo,gridFS,JAVA)