SpringBoot整合Minio

1. Minio介绍

1.1 什么是Minio

Minio 是一个基于Apache License v2.0开源协议的对象存储服务。它可以运行在多种操作系统上,包括 Linux 和 Windows 等。

它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5TB不等。

Minio官网地址:MinIO | 用于AI的S3 & Kubernetes原生对象存储

Minio官方文档:技术文档

1.2 Minio的特点

  1. 简单易用: Minio的安装和配置非常简单,只需要下载并运行相应的二进制文件即可。它提供了一个Web UI,可以通过界面管理存储桶和对象。

  2. 可扩展性: Minio可以轻松地扩展到多个节点,以提供高可用性和容错能力。它支持多种部署模式,包括单节点、主从复制和集群等。

  3. 高可用性: Minio提供了多种机制来保证数据的可靠性和可用性,包括冗余备份、数据复制和故障转移等。

  4. 安全性: Minio提供了多种安全机制来保护数据的机密性和完整性,包括SSL/TLS加密、访问控制和数据加密等。

  5. 多语言支持: Minio支持多种编程语言,包括Java、Python、Ruby和Go等。

  6. 社区支持: Minio是一个开源项目,拥有庞大的社区支持和贡献者。它的源代码可以在GitHub上获得,并且有一个活跃的邮件列表和论坛。

  7. 对象存储: Minio的核心功能是对象存储。它允许用户上传和下载任意数量和大小的对象,并提供了多种API和SDK来访问这些对象。

  8. 块存储: Minio还支持块存储,允许用户上传和下载大型文件(例如图像或视频)。块存储是一种快速、高效的方式来处理大型文件。

  9. 文件存储: Minio还支持文件存储,允许用户上传和下载单个文件。文件存储是一种简单、快速的方式来处理小型文件。

2. Minio安装

2.1 Windows安装Minio

2.1.1 在D盘创建一个Minio的文件夹,并在里面建两个空的文件夹,一个是bin,一个是data

bin文件夹放下载的exe程序

data文件夹存储文件

2.1.2 下载Minio

下载地址:MinIO下载和安装 | 用于创建高性能对象存储的代码和下载内容

2.1.3 把下载好的 minio.exe 放到 2.1.1 创建的 bin 文件夹下
2.1.4 启动Minio

注意:不要双击运行!!!不要双击运行!!!不要双击运行!!!

在bin文件夹下,点击路径输入cmd,回车打开cmd窗口,或者通过命令定位到【D:\Minio\bin】文件夹中,输入下方命令,启动MinIO服务,不需要进行其他操作

.\minio.exe server D:\Minio\data

注意:

启动后会显示minio的访问地址,默认的用户名和密码。

关闭窗口将停止minio服务器并结束该过程。

2.1.5 浏览器打开上面地址,输入用户名,密码,进行访问
2.1.6 固定端口访问
.\minio.exe server D:\Minio\data --console-address :9001 --address :9000

客户端端口:--console-address :9001

服务器端口:--address :9000

2.1.7 修改用户名,密码

设置账号(至少3位):setx MINIO_ROOT_USER minioroot

设置密码(至少8位):setx MINIO_ROOT_PASSWORD minioroot

setx MINIO_ROOT_USER minioroot

setx MINIO_ROOT_PASSWORD minioroot
2.18 创建 bat 启动文件

创建 runMinio.txt,复制下面的命令保存,修改文件名 runMinio.bat

cmd /c "cd /d D:\Minio\bin&& .\minio.exe server D:\Minio\data

cmd /c "cd /d D:\Minio\bin&& .\minio.exe server D:\Minio\data --console-address :9001 --address :9000

下面的命令存后,双击运行,cmd窗口只是一闪而过,会加到服务里面

打开任务管理器,会发现minio服务是启动的,但是原来的cmd窗口已经被隐藏了

@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("""%~nx0"" h",0)(window.close)&&exit
:begin
REM
cmd /c "cd /d D:\Minio\bin&& .\minio.exe server D:\Minio\data

@echo off
if "%1" == "h" goto begin
mshta vbscript:createobject("wscript.shell").run("""%~nx0"" h",0)(window.close)&&exit
:begin
REM
cmd /c "cd /d D:\Minio\bin&& .\minio.exe server D:\Minio\data --console-address :9001 --address :9000

2.2 Linux安装Minio

2.2.1 在 home 路径下面创建 Minio 文件夹
2.2.2 下载
wget https://dl.min.io/server/minio/release/linux-amd64/minio
2.2.3 添加执行权限给MinIO文件
chmod +x minio
2.2.4 在 home/Minio下面创建 data 文件夹,做为文件存储路径
2.2.5 启动
./minio server /home/Minio/data

./minio.exe server /home/Minio/data --console-address :9001 --address :9000

后台执行

nohup /home/Minio/minio server /home/Minio/data --console-address :9001 --address :9000 > /dev/null 2>&1 &

2.3 创建 Bucket

2.3 创建 Access Key

3. Springboot接入Minio

3.1创建Springboot项目

3.2 pom文件添加依赖

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

3.3 application.yml添加配置

#minio配置(下面四个都要替换成自己的)
minio:
  access-key: li5fasdfaeWFR344W2
  secret-key: p4VIZ23948ASDFJAjasdif2UFSDFc9b
  url: http://169.254.19.42:9000
  bucket-name: file

3.4 编写MinioConfig 配置类

package com.minio.config;

import io.minio.MinioClient;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
    private String accessKey;

    private String secretKey;

    private String url;

    private String bucketName;

    @Bean
    public MinioClient minioClient(){
        return MinioClient.builder()
                .region("cn-north-1")
                .endpoint(url)
                .credentials(accessKey,secretKey)
                .build();
    }
}

3.5 编写MinioUtil工具类

package com.minio.utils;

import com.minio.config.MinioConfig;
import io.minio.*;
import io.minio.http.Method;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;

import java.net.URLEncoder;
import java.util.concurrent.TimeUnit;

@Component
public class MinioUtil {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConfig configuration;

    /**
     * 判断bucket是否存在,不存在则创建
     */
    public boolean existBucket(String bucketName) {
        boolean exists;
        try {
            exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                exists = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
            exists = false;
        }
        return exists;
    }

    /**
     * 删除bucket
     */
    public Boolean removeBucket(String bucketName) {
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 上传文件
     *
     * @param file     文件
     * @param fileName 文件名称
     */
    public void upload(MultipartFile file, String fileName) {
        // 使用putObject上传一个文件到存储桶中。
        try {
            InputStream inputStream = file.getInputStream();
            minioClient.putObject(PutObjectArgs.builder()
                    .bucket(configuration.getBucketName())
                    .object(fileName)
                    .stream(inputStream, file.getSize(), -1)
                    .contentType(file.getContentType())
                    .build());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取文件访问地址(有过期时间)
     *
     * @param fileName 文件名称
     * @param time     时间
     * @param timeUnit 时间单位
     */
    public String getExpireFileUrl(String fileName, int time, TimeUnit timeUnit) {
        try {
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(configuration.getBucketName())
                    .object(fileName)
                    .expiry(time, timeUnit).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取文件访问地址
     *
     * @param fileName 文件名称
     */
    public String getFileUrl(String fileName) {
        try {
            return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                    .method(Method.GET)
                    .bucket(configuration.getBucketName())
                    .object(fileName)
                    .build()
            );
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 下载文件
     *
     * @param fileName 文件名称
     */
    public void download(HttpServletResponse response, String fileName) {
        InputStream in = null;
        try {
            // 获取对象信息
            StatObjectResponse stat = minioClient.statObject(StatObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
            response.setContentType(stat.contentType());
            response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            // 文件下载
            in = minioClient.getObject(GetObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
            IOUtils.copy(in, response.getOutputStream());
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 删除文件
     *
     * @param fileName 文件名称
     */
    public void delete(String fileName) {
        try {
            minioClient.removeObject(RemoveObjectArgs.builder().bucket(configuration.getBucketName()).object(fileName).build());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

3.6 编写UploadController

package com.minio.controller;

import com.minio.utils.MinioUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.UUID;

/**
 * @author liyh
 */
@RestController
@RequestMapping("/api")
public class UploadController {

    @Autowired
    private MinioUtil minioUtil;

    /**
     * 上传文件
     */
    @PostMapping(value = "/upload")
    public String uploadReport(MultipartFile[] files) {
        for (MultipartFile file : files) {
            String fileName = file.getOriginalFilename();
            String rename = UUID.randomUUID().toString();
            minioUtil.upload(file, rename);
        }
        return "上传成功";
    }

    /**
     * 预览文件
     */
    @GetMapping("/preview")
    public String preview(String fileName) {
        return minioUtil.getFileUrl(fileName);
    }

    /**
     * 下载文件
     */
    @GetMapping("/download")
    public void download(String fileName, HttpServletResponse response) {
        minioUtil.download(response, fileName);
    }

    /**
     * 删除文件
     */
    @GetMapping("/delete")
    public String delete(String fileName) {
        minioUtil.delete(fileName);
        return "删除成功";
    }

}

4. 启动项目测试

4.1 上传文件

http://127.0.0.1:8088/api/upload

4.2 预览文件

http://127.0.0.1:8088/api/preview?fileName=

4.3 下载文件

http://127.0.0.1:8088/api/download?fileName=

4.4 删除文件

http://127.0.0.1:8088/api/delete?fileName=

5. 完整项目地址(Gitee

相关推荐
狂放不羁霸8 分钟前
idea | 搭建 SpringBoot 项目之配置 Maven
spring boot·maven·intellij-idea
九圣残炎9 分钟前
【从零开始的LeetCode-算法】1456. 定长子串中元音的最大数目
java·算法·leetcode
wclass-zhengge11 分钟前
Netty篇(入门编程)
java·linux·服务器
计算机学长felix35 分钟前
基于SpringBoot的“校园交友网站”的设计与实现(源码+数据库+文档+PPT)
数据库·spring boot·毕业设计·交友
Re.不晚38 分钟前
Java入门15——抽象类
java·开发语言·学习·算法·intellij-idea
雷神乐乐44 分钟前
Maven学习——创建Maven的Java和Web工程,并运行在Tomcat上
java·maven
码农派大星。1 小时前
Spring Boot 配置文件
java·spring boot·后端
顾北川_野1 小时前
Android 手机设备的OEM-unlock解锁 和 adb push文件
android·java
江深竹静,一苇以航1 小时前
springboot3项目整合Mybatis-plus启动项目报错:Invalid bean definition with name ‘xxxMapper‘
java·spring boot
confiself1 小时前
大模型系列——LLAMA-O1 复刻代码解读
java·开发语言