当前位置: 首页 > news >正文

minio + linux + docker + spring boot实现文件上传与下载

minio + docker + spring boot实现文件上传与下载

  • 1.在linux上安装并启动docker
  • 2.在docker中拉取minio并启动
  • 3.Spring Boot 整合 minio
  • 4.测试 minio 文件上传、下载及图片预览等功能

1.在linux上安装并启动docker

  • 检查linux内核,必须是3.10以上
uname ‐r
  • 安装docker
yum install docker
  • 启动docker
systemctl start docker

2.在docker中拉取minio并启动

  • 搜索镜像
docker search minio

在这里插入图片描述

  • 拉取镜像
docker pull minio/minio

在这里插入图片描述

  • 启动minio
docker run  -p 9000:9000 -p 9090:9090 --name minio \-d --restart=always \-e MINIO_ACCESS_KEY=vinci \-e MINIO_SECRET_KEY=123456\-v /usr/local/minio/data:/data \-v /usr/local/minio/config:/root/.minio \minio/minio server /data  --console-address ":9000" --address ":9090"

-p: 指定端口映射,格式为:主机端口:容器端口 (这里注意要映射两个,否则API会访问不到)
-e “MINIO_ROOT_USER=vinci” minio用户名;
-e MINIO_SECRET_KEY=123456 minio 密码
-d: 后台运行容器,并返回容器ID;
-v: 绑定一个卷

这里可以看到minio已经在docker里启动起来了
在这里插入图片描述

接下来我们可以通过以下命令来查看 minio console和minio api 访问端口

docker logs minio

在这里插入图片描述

  • 访问minio控制台
    在此步骤前记得开放端口号
    在这里插入图片描述
    我们接下来可以使用密码和账号登录minio控制台了

3.Spring Boot 整合 minio

在此之前我们可以先通过控制台来创建一个bucket
在这里插入图片描述

  • 集成minio
<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.4.0</version>
</dependency>
  • 编写minio配置类
/*** @package: com.vinci.minio.config* @className: MinioConfig* @author: Vinci* @description: minio配置类* @date: 2023/10/27 13:10*/
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {private String endpoint;private String accessKey;private String secretKey;private String bucketName;@Beanpublic MinioClient minioClient(){return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();}}
  • 在application.properties中添加以下配置
minio.endpoint=http://108.13.21.28:9090/ 
minio.bucket-name=images
minio.access-key=xxxxx
minio.secret-key=xxxxx

注意 minio.endpoint 是minio API地址,不是控制台地址
minio.bucket-name 是 bucket的名称
minio.access-key 是用户名
minio.secret-key是密码

  • 编写minio工具类
package com.vinci.minio.utils;import com.vinci.minio.config.MinioConfig;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;/*** @description: minio工具类* @author: Vinci* @date: 2023/10/27 13:23**/
@Component
@Slf4j
public class MinioUtil {@Resourceprivate MinioConfig config;@Resourceprivate MinioClient minioClient;/*** @description: 查看存储bucket是否存在* @author: Vinci* @date: 2023/10/27 13:24* @param bucketName 要查看的bucket名称* @return 存在即返回true**/public Boolean bucketExists(String bucketName) {try {return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());} catch (Exception e) {log.error("发现异常",e);return false;}}/*** @description: 创建存储bucket* @author: Vinci* @date: 2023/10/27 13:24* @param bucketName 要创建的bucket名称* @return 创建成功即返回true**/public Boolean makeBucket(String bucketName) {try {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());return true;} catch (Exception e) {log.error("发现异常",e);return false;}}/*** @description: 删除存储bucket* @author: Vinci* @date: 2023/10/27 13:24* @param bucketName 要删除的bucket名称* @return 删除成功即返回true**/public Boolean removeBucket(String bucketName) {try {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());return true;} catch (Exception e) {log.error("发现异常",e);return false;}}/*** @description: 获取全部bucket* @author: Vinci* @date: 2023/10/27 13:24* @return 返回bucket结果集**/public List<Bucket> getAllBuckets() {try {return minioClient.listBuckets();} catch (Exception e) {log.error("发现异常",e);return null;}}/*** @description: 文件上传* @author: Vinci* @date: 2023/10/27 13:24* @param file 表单上传的文件* @return 返回文件上传的路径**/public String upload(MultipartFile file) {String originalFilename = file.getOriginalFilename();if (originalFilename == null || originalFilename.isEmpty()){throw new RuntimeException();}String fileName = UUID.randomUUID() + originalFilename.substring(originalFilename.lastIndexOf("."));String objectName = new SimpleDateFormat("yyyyMM").format(new Date()) + "/" + fileName;try {PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(config.getBucketName()).object(objectName).stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();minioClient.putObject(objectArgs);return objectName;} catch (Exception e) {log.error("发现异常",e);return null;}}/*** @description: 预览图片* @author: Vinci* @date: 2023/10/27 13:24* @param fileName 文件在bucket中的全路径* @return 返回文件的浏览路径**/public String preview(String fileName){// 查看文件地址GetPresignedObjectUrlArgs build = GetPresignedObjectUrlArgs.builder().bucket(config.getBucketName()).object(fileName).method(Method.GET).build();try {return minioClient.getPresignedObjectUrl(build);} catch (Exception e) {log.error("发现异常",e);return null;}}/*** @description: 文件下载* @author: Vinci* @date: 2023/10/27 13:24* @param fileName 文件在bucket中的全路径**/public void download(String fileName, HttpServletResponse res) {GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(config.getBucketName()).object(fileName).build();try (GetObjectResponse response = minioClient.getObject(objectArgs)){byte[] buf = new byte[1024];int len;try (FastByteArrayOutputStream os = new FastByteArrayOutputStream()){while ((len=response.read(buf))!=-1){os.write(buf,0,len);}os.flush();byte[] bytes = os.toByteArray();res.setCharacterEncoding("utf-8");res.setContentType("application/force-download");res.addHeader("Content-Disposition", "inline;fileName=" + fileName);try (ServletOutputStream stream = res.getOutputStream()){stream.write(bytes);stream.flush();}}} catch (Exception e) {log.error("发现异常",e);}}/*** @description: 查看文件对象* @author: Vinci* @date: 2023/10/27 13:24* @return 存储bucket内文件对象信息**/public List<Item> listObjects() {Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(config.getBucketName()).build());List<Item> items = new ArrayList<>();try {for (Result<Item> result : results) {items.add(result.get());}return items;} catch (Exception e) {log.error("发现异常",e);return null;}}/*** @description: 删除文件信息* @author: Vinci* @date: 2023/10/27 13:24* @return 删除成功则返回true**/public boolean remove(String fileName){try {minioClient.removeObject(RemoveObjectArgs.builder().bucket(config.getBucketName()).object(fileName).build());return true;}catch (Exception e){log.error("发现异常",e);return false;}}}

4.测试 minio 文件上传、下载及图片预览等功能

  • 编写controller通过接口的方式来测试minio功能
package com.vinci.minio.controller;import com.vinci.minio.utils.MinioUtil;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;/*** @package: com.vinci.minio.controller* @className: TestMinioController* @author: Vinci* @description: 测试minio* @date: 2023/10/27 13:48*/
@Controller
@RequestMapping(value = "/minio")
public class TestMinioController {@Resourceprivate MinioUtil minioUtil;/*** @description: 文件上传测试* @author: Vinci* @date: 2023/10/27 13:48**/@ResponseBody@PostMapping("/upload")public String fileUpload(MultipartFile file) {return minioUtil.upload(file);}/*** @description: 文件下载测试* @author: Vinci* @date: 2023/10/27 13:51**/@ResponseBody@GetMapping("/download")public String fileDownload(String fileName, HttpServletResponse response){minioUtil.download(fileName,response);return "success";}/*** @description: 图片预览* @author: Vinci* @date: 2023/10/27 13:53**/@GetMapping("/preview")public String imagePreview(String fileName){return minioUtil.preview(fileName);}}
  • 测试文件上传
    使用postMan来调用文件上传的接口
    在这里插入图片描述
    我们返回控制台可以看到文件已经上传上去了
    在这里插入图片描述
  • 测试文件下载
    在这里插入图片描述
    我们借助postman工具点击发送并下载可以看到文件下载成功了
    在这里插入图片描述
    在这里插入图片描述
  • 图片在线预览
    在这里插入图片描述
    我们同样借助postman工具发送请求,我们可以看到返回了图片的在线浏览地址,点击即可在线浏览图片
    在这里插入图片描述
    以上便是minio 整合springboot的全部流程了,感谢阅读!
    SpringBoot案例地址:https://gitee.com/vinci99/springboot-minio-test.git

相关文章:

minio + linux + docker + spring boot实现文件上传与下载

minio docker spring boot实现文件上传与下载 1.在linux上安装并启动docker2.在docker中拉取minio并启动3.Spring Boot 整合 minio4.测试 minio 文件上传、下载及图片预览等功能 1.在linux上安装并启动docker 检查linux内核&#xff0c;必须是3.10以上 uname ‐r安装docker…...

vue ant DatePicker 日期选择器 限制日期可控范围

场景 限制当前日期之前不能选择 限制只能选择日期区间内 Ant Design Vue 效果 <a-date-picker :disabledDate"disabledDate"></a-date-picker>method // 限制日期选择disabledDate(current) {return current && current > moment().endOf(&…...

linux 音视频架构 linux音视频开发

linux 音视频架构 linux音视频开发 转载 mob6454cc65110a 2023-07-26 22:27:01 文章标签 linux 音视频架构 ci QT 视频教程 文章分类 架构 后端开发 阅读数117 目录 前言1、软件工具准备a. 录音软件b. 录屏软件c. 摄像头软件d. 安卓屏幕操作软件e. 视频剪辑软件2、视频教…...

el-table添加固定高度height后高度自适应

0 效果 1 添加自定义指令 新建目录src/directive/el-table 在el-table目录下新建文件adaptive.js import { addResizeListener, removeResizeListener } from element-ui/src/utils/resize-event// 设置表格高度const doResize async(el, binding, vnode) > {// 获取表格…...

Python分享之多进程探索 (multiprocessing包)

在初步了解Python多进程之后&#xff0c;我们可以继续探索multiprocessing包中更加高级的工具。这些工具可以让我们更加便利地实现多进程。 进程池 进程池 (Process Pool)可以创建多个进程。这些进程就像是随时待命的士兵&#xff0c;准备执行任务(程序)。一个进程池中可以容…...

Boris FX Mocha Pro 2023:Mac/win全能影像处理神器

Boris FX Mocha Pro 2023是一款广受欢迎的影像处理软件&#xff0c;它凭借其强大的功能和卓越的性能&#xff0c;成为了影视后期、广告制作、动画设计等领域的必备工具。无论您是专业的影视制作人员&#xff0c;还是初入行的新手&#xff0c;Boris FX Mocha Pro 2023都能为您的…...

elementUI 特定分辨率(如1920*1080)下el-row未超出一行却换行

在1920*1080分辨率下&#xff0c; el-col 内容未超出 el-col 宽度&#xff0c;el-col 不足以占据一行&#xff0c;el-row 却自动换行了&#xff08;其他分辨率没有这个问题&#xff09;。 截图&#xff1a; 排查&#xff1a; el-col 内容没有溢出&#xff1b;没有多余的 pad…...

mac电脑视频处理推荐:达芬奇DaVinci Resolve Studio 18 中文最新

DaVinci Resolve Studio 18是一款专业的视频编辑、调色和后期制作软件&#xff0c;由Blackmagic Design开发。它被广泛应用于电影、电视和广告等行业&#xff0c;提供了全面的工具和功能&#xff0c;使用户能够进行高质量的影片制作和后期处理。 以下是DaVinci Resolve Studio…...

OKLink携手CertiK在港举办Web3生态安全主题论坛

2023年10月23日&#xff0c;OKLink与CertiK共同发起的Web3生态安全主题论坛在香港铜锣湾拉开帷幕。本次论坛由OKLink和CertiK主办&#xff0c;香港投资推广署独家支持&#xff0c;聚焦如何构建安全可靠的Web3生态系统议题&#xff0c;同时深入剖析这一进程中所面临的潜在挑战。…...

王道p40 1.设计一个递归算法,删除不带头结点的单链表L中的所有值为x的结点(c语言代码实现)图解递归

视频讲解(献丑了)&#xff1a;p40 第1题 王道数据结构课后代码题c语言代码实现_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Xa4y1Q7ui/?spm_id_from333.999.0.0 首先它是一个不带头结点的单链表 我们就得特殊处理 我们先让*LNULL&#xff1b; 然后为s开辟一个新…...

深入浅出排序算法之希尔排序

目录 1. 原理 2. 代码实现 3. 性能分析 1. 原理 希尔排序法又称缩小增量法。希尔排序法的基本思想是&#xff1a;先选定一个整数&#xff0c;把待排序文件中所有记录分成个组&#xff0c;所有距离为的记录分在同一组内&#xff0c;并对每一组内的记录进行排序。然后&#xf…...

close excel by keyword 根据关键字关闭 excel 窗口 xlwings 方式实现

根据标题关键字关闭 workbook&#xff0c;如果没有打开的 workbook 则退出 excel xlwings 方式实现 更方便快捷 def close_excel_by_keyword(keyword):if ~$ in keyword:returnapp xw.apps.activefor workbook in app.books:if keyword in workbook.name:workbook.close()fi…...

LIO-SAM算法解析

文章目录 简介算法概述1.点云去畸变1.1 主要功能1.2 主要流程 2.特征提取3.IMU预积分4.地图优化5.算法评估 简介 LIO-SAM在lego-loam的基础上新增了对IMU和GPS的紧耦合&#xff0c;采用一个因子图对位姿进行优化&#xff0c;包括IMU因子&#xff0c;激光里程计因子&#xff0c…...

vscode 提升小程序开发效率的必备插件与工具

1&#xff0c;微信小程序开发助手&#xff08;WeChat Snippet&#xff09;&#xff1a;提供了小程序代码片段、模板和快速生成页面的功能&#xff0c;加快了开发速度。 2&#xff0c;小程序助手&#xff08;Minapp&#xff09;&#xff1a;提供了小程序项目创建、编译、预览和…...

第五章单元测试

一、学习目的与要求 本章对单元测试进行了详细的介绍。通过本章的学习&#xff0c;应掌握单元测试的概念&#xff0c;了解单元测试的误区&#xff0c;掌握单元测试的策略、分析方法和用例设计方法。 二、考核知识点与考核目标 &#xff08;一&#xff09;单元测试的概念&#…...

【JAVA基础】多线程与线程池

多线程与线程池 文章目录 多线程与线程池1. 相关概念1.1 线程调度1.2 守护线程 2. 生命周期3. 同步机制/同步锁3.1 synchronized3.2 lock3.3 synchronized 与 Lock 的对比 4. 死锁5. 线程通信5.1 线程间的通信5.2 等待唤醒机制5.3 举例5.4 调用 wait 和 notify 需注意的细节5.5…...

HCIA数据通信——交换机(Vlan间的通信与安全)

前言 之前的提到了交换机的概念和实验。不过交换机的一些功能还没有说完&#xff0c;我们的实验也仅仅是阻止相同地址段的IP地址互通&#xff0c;也没有用到子接口和路由器。显然&#xff0c;那样的配置过于简单。 端口安全 Port Security&#xff08;端口安全&#xff09;的功…...

Linux shell编程学习笔记16:bash中的关联数组

上一节我们探讨了普通的数组&#xff0c;即使用数字下标来索引数组中不同的元素的数组&#xff0c;也可以称之为索引数组。 相比纯粹的数字&#xff0c;字符串不仅能表明含义&#xff0c;也更便于记忆使用&#xff0c;于是就有了关联数组。 一、关联数组概述 bash 从4.0开始支…...

浏览器是怎么执行JS的?——消息队列与事件循环

看完渡一的课后&#xff0c;感觉这块内容确实非常重要&#xff0c;写 JS 的连 JS 的执行原理都不知道可不行。 事件循环 在写 JS 的时候&#xff0c;你有没有想过 JS 是按照什么顺序执行的&#xff1f;浏览器是怎么执行 JS 代码的&#xff1f;为什么有时候代码没有按照我们认为…...

IMU预积分的过程详解

一、IMU和相机数据融合保证位姿的有效性&#xff1a; 当运动过快时&#xff0c;相机会出现运动模糊&#xff0c;或者两帧之间重叠区域太少以至于无法进行特征匹配&#xff0c;所以纯视觉SLAM对快速的运动很敏感。而有了IMU&#xff0c;即使在相机数据无效的那段时间内&#xff…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

IGP(Interior Gateway Protocol,内部网关协议)

IGP&#xff08;Interior Gateway Protocol&#xff0c;内部网关协议&#xff09; 是一种用于在一个自治系统&#xff08;AS&#xff09;内部传递路由信息的路由协议&#xff0c;主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!

一、引言 在数据驱动的背景下&#xff0c;知识图谱凭借其高效的信息组织能力&#xff0c;正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合&#xff0c;探讨知识图谱开发的实现细节&#xff0c;帮助读者掌握该技术栈在实际项目中的落地方法。 …...

DeepSeek 技术赋能无人农场协同作业:用 AI 重构农田管理 “神经网”

目录 一、引言二、DeepSeek 技术大揭秘2.1 核心架构解析2.2 关键技术剖析 三、智能农业无人农场协同作业现状3.1 发展现状概述3.2 协同作业模式介绍 四、DeepSeek 的 “农场奇妙游”4.1 数据处理与分析4.2 作物生长监测与预测4.3 病虫害防治4.4 农机协同作业调度 五、实际案例大…...

服务器--宝塔命令

一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行&#xff01; sudo su - 1. CentOS 系统&#xff1a; yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...

回溯算法学习

一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...

解析奥地利 XARION激光超声检测系统:无膜光学麦克风 + 无耦合剂的技术协同优势及多元应用

在工业制造领域&#xff0c;无损检测&#xff08;NDT)的精度与效率直接影响产品质量与生产安全。奥地利 XARION开发的激光超声精密检测系统&#xff0c;以非接触式光学麦克风技术为核心&#xff0c;打破传统检测瓶颈&#xff0c;为半导体、航空航天、汽车制造等行业提供了高灵敏…...