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

news2024/11/13 9:10:11

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集合存储文件的二进制数据块。

在这里插入图片描述

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.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </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文件等则直接下载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2085739.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记URL重定向漏洞骚技巧

0x1 前言 这几天跟着我那几个师傅们在学习URL重定向漏洞&#xff0c;学习了比较多的对于这个漏洞的骚技巧&#xff0c;以及在挖掘edusrc漏洞和企业src相关的URL重定向漏洞时的一些技巧和不错的思路。 最近在跟我那几个师傅们研究学习URL重定向漏洞&#xff0c;然后在一些厂商…

EHS综合管理解决方案落地:管理效率飞升70%!

所有制造企业都面临着一个问题&#xff1a;如何保证EHS制度高质、高效执行&#xff1f;——上海斯歌EHS综合管理解决方案应运而生。 前不久&#xff0c;上海斯歌EHS综合管理解决方案&#xff08;企业安环综合管理解决方案&#xff09;在某全球领先的汽配公司成功落地&#xff0…

安灯系统在汽车电子工厂应用案例汇总

在汽车电子工厂中&#xff0c;高效的生产管理和及时的问题解决至关重要。安灯系统作为精益制造执行中的核心工具也是 MES 制造执行系统的重要组成部分&#xff0c;为汽车电子工厂带来了显著的效益。安灯系统是一个面向制造业生产现场&#xff0c;快速联络生产、物料、维修、主管…

VSCode中TypeScript调试配置

一、背景 最近想用TypeScript编译项目&#xff0c;在创建完项目后&#xff0c;我发现VSCode只有在调试TypeScript的单个文件时生效&#xff0c;如果存在引用&#xff0c;再进行断点调试&#xff0c;则调试功能不生效了。 随后&#xff0c;我让Chatgpt 生成一个一套配置&#…

C语言基础(二十五)

栈排序不是最高效的方法&#xff0c;因为栈是一种后进先出&#xff08;LIFO, Last In First Out&#xff09;的数据结构&#xff0c;而排序要求根据元素的顺序&#xff08;如升序或降序&#xff09;重新排列。但是&#xff0c;可以利用栈的特性&#xff0c;结合其他排序算法的思…

group by 中一定要包含 select 中的 除聚合函数以外 的 所有字段

今天在项目过程中报错&#xff1a; ### SQL: SELECT UNIT_NAME,dc.CAPTION as area,ifnull(a.bgSum,0) AS bgSum,ifnull(concat(FORMAT(a.bgSum/k.m*100,1),%),0.0%) as bgRatio FROM inspection_station_info isi left join dic_content dc on dc.CODE_VALUE…

K 线图快速绘制教程:使用 KLineChart 展示 DolphinDB K 线

KLineChart 是一款开源、简单易用、适用场景丰富的 Web 前端金融图表&#xff0c;基于 html5 canvas 构建&#xff0c;零依赖压缩包仅 40K&#xff0c;非常轻量。它可以用于渲染金融 K 线图&#xff0c;同时支持多种数据源&#xff0c;提供了丰富的交互功能以及指标计算接口。由…

动物消消乐:Scratch消除类游戏作品

小虎鲸Scratch资源站-免费Scratch作品源码,素材,教程分享平台! 体验《动物消消乐》&#xff0c;开启欢乐消除之旅&#xff01; 在这个快节奏的时代&#xff0c;放松心情、享受乐趣显得尤为重要。小虎鲸Scratch资源站为您带来了全新的游戏体验——《动物消消乐》。这款游戏不仅…

【CTF Web】BUUCTF Upload-Labs-Linux Pass-01 Writeup(JS分析+代码审计+文件上传)

Upload-Labs-Linux 1 点击部署靶机。 简介 upload-labs是一个使用php语言编写的&#xff0c;专门收集渗透测试和CTF中遇到的各种上传漏洞的靶场。旨在帮助大家对上传漏洞有一个全面的了解。目前一共20关&#xff0c;每一关都包含着不同上传方式。 注意 1.每一关没有固定的…

上班摸鱼的人怎么治理?只要5个步骤让员工服服帖帖,打造干净职场

在职场中&#xff0c;我们时常会遇到一些同事在上班时间“摸鱼”&#xff0c;比如浏览与工作无关的网站、玩游戏、聊天等。这些行为不仅影响了工作效率&#xff0c;还可能损害团队的整体氛围和企业的利益。那么&#xff0c;如何有效地治理这种“摸鱼”现象呢&#xff1f;今天&a…

鸿蒙ArkTS小案例-购物车

最近用鸿蒙的ArkTS做了一个购物车的小案例&#xff0c;在这里分享一下&#xff0c;该购物车已实现如下功能&#xff1a; 1. 购物车商品数量支持1个或者多个 2. 勾选1个或者多个商品后&#xff0c;底部可以动态计算出购买总数量和总价格 3. 同时&#xff0c;可以对购买商品的…

SpringBoot对接Midjourney Api

提示&#xff1a;SpringBoot对接Midjourney Api 文章目录 目录 文章目录 后端代码 导包 controller层 工具类层 前端代码 申请API 测试结果 后端代码 导包 <!--添加hutool的依赖--><dependency><groupId>cn.hutool</groupId><artifactId&g…

IoT客户端+联邦学习微调大模型

大型模型的训练涉及到微调&#xff0c;微调则面临着高质量数据的稀缺性。与基于集中式数据中心的解决方案相比&#xff0c;物联网-IoT中大型模型的更新面临着分布式客户端私有且异构数据的协调挑战。为了解决这一挑战&#xff0c;作者提出了KOALA来推动物联网中大模型的训练。由…

单线程Redis:Redis为什么这么快

1 Redis是不是单线程 Redis 使用后台线程执行耗时的 I/O 操作&#xff0c;以免阻塞主线程 bio_close_file&#xff1a;后台 I/O 线程之一&#xff0c;异步关闭文件 bio_aof_fsync&#xff1a;后台 I/O 线程之一&#xff0c;异步地将 AOF&#xff08;Append Only File&#xff…

C++系列-STL容器之vector

STL概念 vector基本概念vector与数组的区别vector容器的特点动态大小连续存储自动扩容尾部操作高效 vector动态扩展的含义vector常用的接口示意 vector的构造函数vector赋值操作重载赋值assign赋值 vector的容量和大小vector的插入和删除vector数据存取vector互换容器vector互换…

音视频入门基础:WAV专题(7)——FFmpeg源码中计算WAV音频文件每个packet的size值的实现

一、引言 从文章《音视频入门基础&#xff1a;WAV专题&#xff08;6&#xff09;——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道&#xff0c;通过FFprobe命令可以显示WAV音频文件每个packet&#xff08;也称为数据包或多媒体包&#xff09;的信息&#xff0…

VMware16安装包+详细安装教程

VMware Workstation Pro16.0安装 安装包下载&#xff1a; 通过百度网盘分享的文件&#xff1a;VMware16.0.rar 链接&#xff1a;https://pan.baidu.com/s/1ZSWns5kJYUmhpZFjuKXqrQ?pwdv7s2 提取码&#xff1a;v7s2右键解压之后的安装包【VMware-workstation-full-16.0.0-16…

FrameNet介绍——从同义词语义知识库到框架语义知识库

FrameNet 是一个为期三年的项目&#xff0c;获得了 NSF&#xff08;美国国家科学基金会&#xff09;的支持&#xff0c;专注于基于语料库的计算词典编纂。 项目特点 FrameNet承诺使用语料库证据&#xff08;corpus evidence&#xff09;来进行语义和句法的概括&#xff1b; 并…

网络基础-实现在Windows系统下的socket环境地址通信

实现客户端和服务端的数据交互 1.写所要实现功能的声明&#xff08;封装在tcpsocket.h文件&#xff09; #ifndef TCPSOCKET_H #define TCPSOCKET_H//在Windows下进行网络编程&#xff0c;需要引入Windows的socket库 #include <winsock2.h> //做一些预编译工作&#xff…

MyBatis结果集复杂映射超详细版(一对多关系映射)

目录 1.一对多关系映射 1.1创建两个表&#xff1a;goods表与goods_class表 1.2xml文件中两部分&#xff1a;与(存放SQL语句)1.3数据库中&#xff1a;测试SQL语句&#xff0c;涉及到的知识点&#xff1a;左连接 1.一对多关系映射 1.1创建两个表&#xff1a;goods表与goods_c…