SpringBoot+Vue3整合minio,实现分布式文件存储

文章目录

      • 几种常用的文件存储
      • 安装和使用minio
      • SpringBoot整合minio

基本所有的软件项目都会需要文件存储功能,图片、视频存储。

几种常用的文件存储

经常用的几种方案,直接存在本地文件夹,开发一个简单的系统当然没有问题。随机系统所需的资源变多,这种情况显然是不可能的。这种适合做一个简单的demo,毕设之类的的系统。
使用第三方的存储服务,如阿里云的oss,十分的方便管理。但是是收费的,如果经费充足也可以考虑。

使用HDFS ,分布式文件存储放方案,大数据领域的文件存储框架,过程配置很繁琐,对于新手来说很不友好。

minio 是一个非常轻量的服务,可以很简单的和其他应用的结合使用,它兼容亚马逊 S3 云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等。
还提供了许多语言的SDK,开发较为方便。

MinIO集群采用去中心化共享架构,每个结点是对等关系,通过Nginx可对MinIO进行负载均衡访问。

安装和使用minio

在linux上面配置mioio过于繁琐。在windows上面也可以运行。
minio的官网:dl.min.io/server/minio/release/windows-amd64/

首先下载minio,下载后是一个.exe文件
image.png

在cmd窗口中运行

//minio.exe   server 启动服务器  后面是对应的节点也就是数据存储的位置,如果上线了就是服务器的地址
minio.exe server E:\develop\data\data1 E:\develop\data\data2 E:\develop\data\data3 E:\develop\data\data4

image.png
image.png
访问mino

在浏览器中输入:http://localhost:9000  跳转到登录页面 账号和密码都是 minioadmin

image.png

登录进去后;
image.png
设置bucket为公有public,可以外部进行访问的。
image.png
image.png
文件的地址就是 ip地址+端口号9000+文件的相对地址
image.png

SpringBoot整合minio

1.导入minio的maven坐标。

<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.3</version>
</dependency>

2.配置yml文件

minio:endpoint: http://127.0.0.1:9000  #文件的前缀 数据存储文件地址应该是相对地址,便于以后更换服务器accessKey: minioadminsecretKey: minioadminbucket:files: mediafilesvideofiles: video

在springBootTest中编写程序

//创建一个minioClient
static MinioClient minioClient =MinioClient.builder().endpoint("http://127.0.0.1:9000").credentials("minioadmin", "minioadmin").build();

3.注册bean,需要用minclient。

import io.minio.MinioClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;//注入到bean中去
@Configuration
public class MinioConfig {@Value("${minio.endpoint}")private String endpoint;@Value("${minio.accessKey}")private String accessKey;@Value("${minio.secretKey}")private String secretKey;@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}
}


FileController

import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import com.njitzx.service.FileService;
import com.njitzx.util.Result;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.File;@RestController
@RequestMapping(value = "/upload")
@Slf4j
public class FileController {private String bucket = "bucket";@Autowiredprivate FileService fileService;@Value("${minio.endpoint}")private String endpoint;/*** 要有一个文件存储的目录?如果判断文件是否已经存在*//*** file 前端传过来的文件*/@PostMapping(consumes = MediaType.MULTIPART_FORM_DATA_VALUE)public Result<String> upload(@RequestParam("file") MultipartFile file) throws Exception {log.info("开始上传文件");System.out.println(file.getOriginalFilename());String suffix = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf("."));File tempFile = File.createTempFile("temp", suffix);file.transferTo(tempFile);String floadName = fileService.upload(tempFile);String url = endpoint + "/" + bucket + "/" + floadName;return Result.success(url);}public static String getMimeType(String extension) {if (extension == null)extension = "";//根据扩展名取出mimeTypeContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(extension);//通用mimeType,字节流String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;if (extensionMatch != null) {mimeType = extensionMatch.getMimeType();}return mimeType;}/*** 删除文件*/
}
import com.j256.simplemagic.ContentInfo;
import com.j256.simplemagic.ContentInfoUtil;
import com.njitzx.service.FileService;import io.minio.MinioClient;
import io.minio.UploadObjectArgs;import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;import java.io.File;import java.io.FileInputStream;
import java.text.SimpleDateFormat;
import java.util.Date;@Service
@Slf4j
public class FileServiceImpl implements FileService {@AutowiredMinioClient minioClient;private String bucket = "bucket";@Overridepublic String upload(File tempFile) {String filename = tempFile.getName();System.out.println(filename);String extension = filename.substring(filename.lastIndexOf("."));String objectname = getDefaultFolderPath() + getFileMd5(tempFile) + extension;System.out.println(objectname);try {UploadObjectArgs uploadObjectArgs = UploadObjectArgs.builder().bucket(bucket).object(objectname).filename(tempFile.getAbsolutePath()).contentType(getMimeType(extension)).build();minioClient.uploadObject(uploadObjectArgs);log.info("上传成功");return objectname;} catch (Exception e) {throw new RuntimeException(e);}}public static String getMimeType(String extension) {if (extension == null)extension = "";//根据扩展名取出mimeTypeContentInfo extensionMatch = ContentInfoUtil.findExtensionMatch(extension);//通用mimeType,字节流String mimeType = MediaType.APPLICATION_OCTET_STREAM_VALUE;if (extensionMatch != null) {mimeType = extensionMatch.getMimeType();}return mimeType;}public static String getFileMd5(File file) {try {FileInputStream fileInputStream = new FileInputStream(file);String filemd5 = DigestUtils.md5DigestAsHex(fileInputStream);return filemd5;} catch (Exception e) {throw new RuntimeException(e.getMessage());}}private String getDefaultFolderPath() {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");String folder = sdf.format(new Date()).replaceAll("-", "/") + "/";return folder;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

微服务多个模块启动,端口被占用,yml配置文件读不到

刚刚提交到gitee自己的仓库&#xff0c;拉下来还是报错&#xff0c;然后看到一个解决方法&#xff1a; <build><resources><resource><directory>src/main/java</directory><includes><include>**/*.yml</include><includ…

推荐一个java低代码开发平台-橙单

文章目录 前言一、项目介绍二、技术选型三、项目特点四、基础功能介绍五、源码下载六、官方文档总结 前言 大家好&#xff0c;今天为大家推荐一个开箱即用&#xff0c;快速开发的低代码平台。项目采用 Boot3 Flowable7 Sa-Token Vue3技术栈。 一、项目介绍 橙单中台化低代…

Datawhale AI 夏令营(第五期) 李宏毅苹果书 Task 1 《深度学习详解(入门)》- 1.1 通过案例了解机器学习

预测本频道观看人数&#xff08;上&#xff09; - 机器学习基本概念简介_哔哩哔哩_bilibili 1 隐藏任务&#xff1a;找出本篇中形如回归&#xff08;regression&#xff09;加粗字体的术语&#xff0c;并用自己的话进行解释&#xff0c;列成表格 术语解释机器学习&#xff08;…

服务器数据恢复—重建RAID失败导致数据丢失的数据恢复案例

服务器数据恢复环境&#xff1a; 某品牌服务器中有一组由4块SAS磁盘做的RAID5磁盘阵列。该服务器操作系统为windows server&#xff0c;运行了一个单节点Oracle&#xff0c;数据存储为文件系统&#xff0c;无归档。该oracle数据库的数据量不大&#xff0c;oracle数据库内只有一…

WPF——动态排名图表实现

开发环境 VS2022 .NET 8.0 MVVM Toolkit 8.2.2 需求 开发中需要实现按照成绩动态指名&#xff0c;以展示当前的竞赛成绩的一个实时情况及变化。 即如下效果&#xff1a; 需求分析 按照接收到的信息&#xff0c;就是要将获取到的集合排序&#xff0c;并且要将排序前后的变…

【AI绘画】Midjourney前置指令/settings设置详解

文章目录 &#x1f4af;Midjourney前置指令/settings设置详解&#x1f4af;Use the default model&#xff08;AI绘画所使用的大模型&#xff09;Midjourney Model&#xff08;Midjourney 模型&#xff09;Niji Model&#xff08;Niji模型&#xff09; &#x1f4af;Midjourney…

外网爆火的LLM应用手册来了!内行人都在学的大模型黑书,豆瓣评分高达9.9!!!

Transformer模型介绍 Transformer 是工业化、同质化的后深度学习模型&#xff0c;其设计目标是能够在高性能计算机(超级计算机)上以并行方式进行计算。通过同质化&#xff0c;一个Transformer 模型可以执行各种任务&#xff0c;而不需要微调。Transformer 使用数十亿参数在数…

【Java数据结构】---二叉树OJ

乐观学习&#xff0c;乐观生活&#xff0c;才能不断前进啊&#xff01;&#xff01;&#xff01; 我的主页&#xff1a;optimistic_chen 我的专栏&#xff1a;c语言 &#xff0c;Java 欢迎大家访问~ 创作不易&#xff0c;大佬们点赞鼓励下吧~ 文章目录 相同的树另一颗树的子树翻…

ES 模糊查询 wildcard 的替代方案探索

一、Wildcard 概述 Wildcard 是一种支持通配符的模糊检索方式。在 Elasticsearch 中&#xff0c;它使用星号 * 代表零个或多个字符&#xff0c;问号 ? 代表单个字符。 其使用方式多样&#xff0c;例如可以通过 {"wildcard": {"field_name": "value&…

docker-compose示例:nacos单机部署

前面咱们完成了docker基本环境搭建&#xff0c;下面就趁热打铁来练习下nacos的单机部署。 参考官方文档&#xff1a;Nacos Docker 快速开始。考虑到官方搭建教程过于精炼&#xff0c;笔者把搭建过程分享给大家。 文章目录 下载最新部署源码解决网络导致的sql文件下不下来docke…

unity AssetBundle 使用_什么是AssetBundle_导入必要的插件_创建AssetBundles_AB包资源下载_大文件下载

一、什么是AssetBundle&#xff1f; 定义AssetBundle。 AssetBundle 是一个存档文件&#xff0c;包含可在运行时由 Unity 加载的特定于平台的非代码资源&#xff08;比如模型、纹理、预制件、音频剪辑甚至整个场景&#xff09;。AssetBundle 可以表示彼此之间的依赖关系&…

防范小程序隐私合规风险,筑牢用户信任防线

随着国内APP软件生态的成熟&#xff0c;依托于头部APP的小程序逐渐成为零售、娱乐、出行等行业必选的获客渠道之一。较低的开发成本和成熟的用户营销功能&#xff0c;令小程序的数量在过去几年呈指数级增长。截止2023年&#xff0c;头部APP内集成的小程序总量已超千万。然而&am…

OpenCV(开源计算机视觉库)

OpenCV&#xff08;开源计算机视觉库&#xff09;是一个专注于实时计算机视觉的全面库&#xff0c;包含了丰富的工具和功能。以下是 OpenCV 中一些关键知识点的详细列表&#xff1a; 核心功能 基本结构&#xff1a;Mat、Scalar、Point、Size、Rect 等。 图像 I/O&#xff1a;读…

Latex 插入图片或表格导致页面空白过多

如图所示&#xff1a; Latex 插入图片或表格导致页面空白过多 我们可以采用这个方式来减少空白。 \documentclass{article} \usepackage{graphicx} % 包含图形支持 \usepackage{caption} % 提供更多对caption的控制% 设置标题上方和下方的间距 \setlength{\abovecaptionskip}{…

数据结构【链试结构二叉树】

&#x1f31f;个人主页&#xff1a;落叶 目录 ​编辑 实现链式结构⼆叉树 前中后序遍历&#xff1a; 遍历规则 代码实现 前序遍历&#xff1a; 中序遍历&#xff1a; 后序遍历&#xff1a; 图解遍历&#xff1a; 函数递归栈帧图&#xff1a; 结点个数以及高度等 【⼆…

Oracle归档日志满了,导致程序打不开,如何解决。

加油&#xff0c;新时代打工人&#xff01; 归档日志错误&#xff0c;登录不上&#xff0c;只能用system 角色登录&#xff0c; 错误提示 oracle 错误257 archiver error connect internal only until freed 解决cmd进入rman RMAN&#xff08;Recovery Manager&#xff09;是一…

数学基础(六)

一、分布 正态分布 二项式分布 均匀分布 卡方分布 二、核函数 核函数的目的&#xff1a; 将低维数据转换为高维数据 线性核函数&#xff1a; Linear核函数对数据不做任何变换 当特征已经比较丰富了&#xff0c;样本数据量巨大&#xff0c;需要进行实时得出结果时进行使用…

小程序学习day11-生命周期函数、组件所在页面的生命周期、自定义组件的插槽、自定义组件的父子通信

40、自定义组件&#xff08;续&#xff09;&#xff08;续&#xff09; &#xff08;10&#xff09;生命周期函数 1&#xff09;小程序里的全部生命周期函数 ①created&#xff08;在组件刚被创建时执行&#xff09;&#xff08;被创建&#xff0c;但未被放入页面&#xff09…

Servlet---axios框架 ▎路由守卫

前言 在现代Web应用中&#xff0c;前端和后端通常分离&#xff0c;前端使用框架&#xff08;如Vue.js、React&#xff09;与后端服务交互。Servlet是Java EE中处理HTTP请求的重要组成部分&#xff0c;能够生成动态Web内容。 Axios是一个基于Promise的HTTP客户端&#xff0c;简…

手机mkv转换mp4:轻松实现视频格式兼容

如今手机已成为我们日常生活中不可或缺的伴侣&#xff0c;而视频文件则是我们享受娱乐、获取信息的重要来源。然而&#xff0c;由于不同设备和平台对视频格式的支持各有不同&#xff0c;我们有时会遇到无法在手机上播放某些视频文件的问题。 mkv是一种常见的视频格式&#xff…