Minio篇:初识MinIO

1. MinIO快速入门

1.1.MinIO核心概念

下面介绍MinIO中的几个核心概念,这些概念在所有的对象存储服务中也都是通用的。

  • 对象(Object)

    对象是实际的数据单元,例如我们上传的一个图片。

  • 存储桶(Bucket)

    存储桶是用于组织对象的命名空间,类似于文件夹。每个存储桶可以包含多个对象。

  • 端点(Endpoint)

    端点是MinIO服务器的网络地址,用于访问存储桶和对象,例如http://192.168.xxx.xxx:9000

    注意:

    9000为MinIO的API的默认端口,前边配置的9001以为管理页面端口。

  • Access Key 和 Secret Key

    Access Key是用于标识和验证访问者身份的唯一标识符,相当于用户名。

    Secret Key是与Access Key关联的密码,用于验证访问者的身份。

1.2.MinIO控制台页面操作

 前提:需要把你的MinIO部署在linux系统上,具体部署过程可看:MinIO官方

1.登录

管理页面的http://192.168.xxx.xxx:9001,登录的用户名和密码为部署时在EnvironmentFile文件中配置的如下参数:

MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minioadmin

2.创建存储桶

3.上传图片

4.访问图片

图片URL

由于MinIO提供了HTTP访问功能,所以可以通过浏览器直接访问对象。对象URL为MinIO的Endpoint+对象的存储路径,例如下图中的图片对象的URL为

192.168.xxx.xxx:9000/lease/a.jpg

访问权限

不出意外的话,使用浏览器访问上述URL,会得到如下响应,很显然是没有访问权限。

若想继续访问图片,需要修改图片所在桶的访问权限,如下图所示  

如上图所示,可选的访问权限共有三个选项,分别是PrivatePublicCustom,具体说明如下

  • Private

    只允许桶的所有者对该桶进行读写。

  • Public

    允许所有人对该桶进行读写。

  • Custom

    自定义访问权限。

若想将权限设置为只允许所有者写,但允许所有人读,就需要自定义访问权限。自定义访问权限,需要使用一个规定格式的JSON字符串进行描述,具体格式可参考官方文档。

例如以下JSON字符串表达的含义是:允许(Allow)所有人(*)读取(s3:GetObject)指定桶(lease)的所有内容。

{"Statement" : [ {"Action" : "s3:GetObject","Effect" : "Allow","Principal" : "*","Resource" : "arn:aws:s3:::lease/*"} ],"Version" : "2012-10-17"
}

重新访问:

192.168.xxx.xxx:9000/lease/a.jpg

 

2. 图片上传接口开发

2.1. Minio相关配置

下面为该接口的具体实现

@ConfigurationProperties(prefix = "minio")
@Data
public class MinioProperties {private String endpoint;private String accessKey;private String secretKey;private String bucketName;
}
  • 配置Minio Client

    • 引入Minio Maven依赖

<dependency><groupId>io.minio</groupId><artifactId>minio</artifactId>
</dependency>
  • 配置Minio相关参数

    application.yml中配置Minio的endpointaccessKeysecretKeybucketName等参数

    minio:endpoint: http://<hostname>:<port>access-key: <access-key>secret-key: <secret-key>bucket-name: <bucket-name>
     注意:上述<hostname><port>等信息需根据实际情况进行修改。

新建一个MinioProperties类:

@ConfigurationProperties(prefix = "minio")
@Data
public class MinioProperties {private String endpoint;private String accessKey;private String secretKey;private String bucketName;
}

新建一个MinioConfiguration类:

@Configuration
@EnableConfigurationProperties(MinioProperties.class)
public class MinioConfiguration {@Autowiredprivate MinioProperties properties;@Beanpublic MinioClient minioClient() {return MinioClient.builder().endpoint(properties.getEndpoint()).credentials(properties.getAccessKey(), properties.getSecretKey()).build();}
}

新建一个工具类:MinioUtil

package com.gjh.lease.common.minio;import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.Item;
import jakarta.annotation.Resource;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.FastByteArrayOutputStream;
import org.springframework.web.multipart.MultipartFile;import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;@Component
@Slf4j
public class MinioUtil {@Autowiredprivate MinioProperties prop;@Autowiredprivate MinioConfiguration minioConfiguration;@Resourceprivate MinioClient minioClient;/*** 查看存储bucket是否存在* @return boolean*/public Boolean bucketExists(String bucketName) {Boolean found;try {found = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return found;}/*** 创建存储bucket* @return Boolean*/public Boolean makeBucket(String bucketName) {try {minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 删除存储bucket* @return Boolean*/public Boolean removeBucket(String bucketName) {try {minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());} catch (Exception e) {e.printStackTrace();return false;}return true;}/*** 获取全部bucket*/public List<Bucket> getAllBuckets() {try {List<Bucket> buckets = minioClient.listBuckets();return buckets;} catch (Exception e) {e.printStackTrace();}return null;}/*** 文件上传** @param file 文件* @return Boolean*/public String upload(MultipartFile file) {String originalFilename = file.getOriginalFilename();if (StringUtils.isBlank(originalFilename)){throw new RuntimeException();}String fileName = new SimpleDateFormat("yyyyMMdd").format(new Date()) +"/" + UUID.randomUUID() + "-" + file.getOriginalFilename();
//        String objectName = CommUtils.getNowDateLongStr("yyyy-MM/dd") + "/" + fileName;String objectName = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")) + "/" + fileName;try {PutObjectArgs objectArgs = PutObjectArgs.builder().bucket(prop.getBucketName()).object(objectName).stream(file.getInputStream(), file.getSize(), -1).contentType(file.getContentType()).build();//文件名称相同会覆盖minioClient.putObject(objectArgs);} catch (Exception e) {e.printStackTrace();return null;}return objectName;}/*** 预览图片* @param fileName* @return*/public String preview(String fileName){// 查看文件地址GetPresignedObjectUrlArgs build = new GetPresignedObjectUrlArgs().builder().bucket(prop.getBucketName()).object(fileName).method(Method.GET).build();try {String url = minioClient.getPresignedObjectUrl(build);return url;} catch (Exception e) {e.printStackTrace();}return null;}/*** 文件下载* @param fileName 文件名称* @param res response* @return Boolean*/public void download(String fileName, HttpServletResponse res) {GetObjectArgs objectArgs = GetObjectArgs.builder().bucket(prop.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", "attachment;fileName=" + fileName);try (ServletOutputStream stream = res.getOutputStream()){stream.write(bytes);stream.flush();}}} catch (Exception e) {e.printStackTrace();}}/*** 查看文件对象* @return 存储bucket内文件对象信息*/public List<Item> listObjects() {Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(prop.getBucketName()).build());List<Item> items = new ArrayList<>();try {for (Result<Item> result : results) {items.add(result.get());}} catch (Exception e) {e.printStackTrace();return null;}return items;}/*** 删除* @param fileName* @return* @throws Exception*/public boolean remove(String fileName){try {minioClient.removeObject( RemoveObjectArgs.builder().bucket(prop.getBucketName()).object(fileName).build());}catch (Exception e){return false;}return true;}}

2.2.开发图片上传接口

controller:

 @Operation(summary = "上传文件")@PostMapping("upload")public Result<String> upload(@RequestParam MultipartFile file) throws Exception {String objectName = minioUtil.upload(file);if(null != objectName){return Result.ok(properties.getEndpoint() + "/" +properties.getBucketName() + "/" + objectName);}return Result.fail();}

这样就可以实现文件上传了。

2.3.测试

 

实现了基于Minio实现文件上传!

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

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

相关文章

基于单片机的机械臂的研究

摘要 &#xff1a; 工业机器人是现代科学技术的融合下的产物&#xff0c;属于机电自动化设备的一种。机械臂作为工业机器人的核心&#xff0c;在提高工业生产效率的同时&#xff0c;也保障了工作人员的身心安全。本文以某款基于单片机的机械臂为例&#xff0c;对机械臂的设计方…

【JAVA SE】多态

✨✨欢迎大家来到Celia的博客✨✨ &#x1f389;&#x1f389;创作不易&#xff0c;请点赞关注&#xff0c;多多支持哦&#x1f389;&#x1f389; 所属专栏&#xff1a;JAVA 个人主页&#xff1a;Celias blog~ 目录 引言 一、多态 1.1 多态的概念 1.2 多态的实现条件 1.3…

AI未来预测

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已经成为了当今世界的热门话题。从自动驾驶汽车到智能家居&#xff0c;从虚拟助手到机器人&#xff0c;AI的应用已经渗透到了我们生活的方方面面。在未来&#xff0c;AI将会继续改变我们的生活方式&#xff0…

深入探讨 Android 的 View 显示过程与源码分析

文章目录 1. 探讨 Android 的 View 显示过程1.1. onFinishInflate1.2. onAttachedToWindow1.3. onMeasure1.4. onSizeChanged1.5. onLayout1.6. onDraw 2. 系统代码分析1.1. onFinishInflate1.2. onAttachedToWindow1.3. onMeasure1.4. onSizeChanged1.5. onLayout1.6. onDraw …

【Spring Boot】SpringBoot 下在 yml 中的 logging 日志配置

文章目录 前言输出日志的级别日志输出的位置日志输出的格式日志文件的存储路径日志文件是否输出到控制台配置Logback 配置日志分组配置日志细粒度配置【logger】 前言 logging 配置主要用于控制应用程序的日志输出行为&#xff0c;可以通过配置定制日志的格式、级别、输出位置…

数字化浪潮中的TPM革新:打造高效生产新范式

在数字化浪潮席卷全球的今天&#xff0c;传统生产管理模式正面临前所未有的挑战与机遇。TPM&#xff08;全面生产维护&#xff09;作为一种先进的生产管理理念&#xff0c;如何在数字化驱动下焕发新的活力&#xff0c;成为制造业转型升级的关键一环。 数字化技术为TPM带来了前…

Ubuntu禁止内核自动更新

查看当前内核版本 uname -v #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 7 09:00:52 UTC 2 uname -a Linux GKJ 6.5.0-35-generic #35~22.04.1-Ubuntu SMP PREEMPT_DYNAMIC Tue May 7 09:00:52 UTC 2 x86_64 x86_64 x86_64 GNU/Linux uname -r 6.5.0-35-generic 方法1&am…

EureKa是什么?

Eureka 是一个源于 Netflix 公司的开源项目&#xff0c;主要用于实现服务注册和服务发现的功能。它是构建分布式系统中的微服务架构的一个关键组件。下面是对 Eureka 的解释&#xff1a; 基本概念 Eureka 是基于 REST 的服务&#xff0c;主要用于管理微服务架构中的服务实例的…

探秘Flask中的表单数据处理

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、引言 二、Flask中的表单处理机制 三、Flask表单处理实战 四、处理表单数据的注意事项…

为什么要使用动态代理IP?

一、什么是动态代理IP&#xff1f; 动态代理IP是指利用代理服务器来转发网络请求&#xff0c;并通过不断更新IP地址来保护访问者的原始IP&#xff0c;从而达到匿名访问、保护隐私和提高访问安全性的目的。动态代理IP在多个领域中都有广泛的应用&#xff0c;能够帮助用户…

vue路由跳转之【编程式导航与传参】

vue路由有两种跳转方式 ----> 编程式与声明式&#xff0c;本文重点讲解vue路由的【编程式导航 】【编程式导航传参 ( 查询参数传参 & 动态路由传参 ) 】等内容&#xff0c;并结合具体案例让小伙伴们深入理解 &#xff0c;彻底掌握&#xff01;创作不易&#xff0c;需要的…

2023年全球DDoS攻击现状与趋势分析

天翼安全科技有限公司副总工程师、运营保障部总经理陈林表示&#xff0c;2023年扫段攻击频次快速增长&#xff0c;成为网络基础设施面临的最大威胁。为躲避防御&#xff0c;低速扫段攻击成为主流达到攻击总数的73.19%&#xff1b;43.26%的C段攻击持续时间小于5分钟&#xff0c;…

医疗器械企业中图纸文件防泄密使用数据透明加密系统

医疗器械行业中因为企业的技术图纸需要保密&#xff0c;现有的从国家层面还是社会层面到个人层面对数据安全的防护意识不断的加强&#xff0c;企业中需要能够防止公司研发设计的图纸文件外泄的情况&#xff0c;透明加密软件无疑是能够帮助企业解密数据防泄密问题的最佳解决方案…

Linux中部署MinIO

Linux中部署MinIO 下载MinIO可执行程序&#xff1a; wget https://dl.min.io/server/minio/release/linux-amd64/minio 添加执行权限&#xff1a; chmod x minio 创建存储目录&#xff0c;例如/data&#xff1a; mkdir -p /data 运行MinIO服务器&#xff0c;需要设置MIN…

【设计模式】JAVA Design Patterns——Factory Method(虚拟构造器模式)

&#x1f50d;目的 为创建一个对象定义一个接口&#xff0c;但是让子类决定实例化哪个类。工厂方法允许类将实例化延迟到子类 &#x1f50d;解释 真实世界例子 铁匠生产武器。精灵需要精灵武器&#xff0c;而兽人需要兽人武器。根据客户来召唤正确类型的铁匠。 通俗描述 它为类…

三维前端项目中用THREEWebGLRenderer于创建渲染器对象

在三维前端项目开发中&#xff0c;可以使用THREE.WebGLRenderer创建渲染器对象。艾斯视觉作为行业ui设计与前端开发服务商很高兴能在这里与你共同探讨&#xff1a;THREE.WebGLRenderer是 Three.js 库中用于将 3D 场景渲染到屏幕上的类。以下是一个示例代码&#xff0c;展示了如…

笔记:weblogic 12c 升级JDK

1&#xff0c;下载JDK 网址&#xff1a;https://www.oracle.com/ Oracle Technical Network ReadMe for Java SE: https://www.oracle.com/java/technologies/java-readme.html Release Notes: https://www.oracle.com/java/technologies/javase/jdk-relnotes-index.html Ja…

element中table的selection-change监听改变的那条数据的下标

<el-table ref"table" :loading"loading" :data"tableData" selection-change"handleSelectionChange"></el-table>当绑定方法selection-change&#xff0c;当选择项发生变化时会触发该事件 // 多选框选中数据handleSele…

truncate IDL_UB1$导致数据库open hang---惜分飞

在一次数据库恢复中,发现IDL_UB1$表被truncate,然后数据库在open过程中会hang住,而且不报任何错误,这里通过试验进行重现.对于这类问题,以前有过类似处理测试&#xff1a;truncate IDL_UB1$恢复试验数据库版本 SQL> select * from v$version; BANNER ---------------------…

vivado原语使用

首先介绍一下原语&#xff1a;其英文名字为Primitive。原语是Xilinx针对其器件特征开发的一系列常用模块的名字&#xff0c;用户可以将其看成Xilinx公司为用户提供的ip&#xff0c;是芯片中的基本元件&#xff0c;代表FPGA中实际拥有的硬件逻辑单元&#xff0c;如LUT&#xff0…