Minio搭建并在SpringBoot中使用完成用户头像的上传

Minio使用搭建并上传用户头像到服务器操作,学习笔记

Minio介绍

minio官网

  • MinIO是一个开源的分布式对象存储服务器,支持S3协议并且可以在多节点上实现数据的高可用和容错。它采用Go语言开发,拥有轻量级、高性能、易部署等特点,并且可以自由选择底层存储介质。

  • MinIO的主要特点包括:

1、高性能:MinIO基于GO语言编写,具有高速、轻量级、高并发等性能特点,还支持多线程和缓存等机制进行优化,可以快速地处理大规模数据。

2、可扩展性:MinIO采用分布式存储模式,支持水平扩展,通过增加节点数量来扩展存储容量和性能,支持自动数据迁移和负载均衡。

3、安全性:MinIO提供了多种安全策略,如访问控制列表(ACL)、服务端加密(SSE)、传输层安全性(TLS)等,可以保障数据安全和隐私。

4、兼容性:MinIO兼容AWS S3 API,还支持其他云服务提供商的API,比如GCP、Azure等,可以通过简单的配置实现互操作性。

5、简单易用:MinIO的部署和管理非常简单,只需要运行一个二进制包即可启动服务,同时提供了Web界面和命令行工具等方便的管理工具。

  • S3协议是Amazon Web Services (AWS) 提供的对象存储服务(Simple Storage Service)的API协议。它是一种 RESTful风格的Web服务接口,使用HTTP/HTTPS协议进行通信,支持多种编程语言和操作系统,并实现了数据的可靠存储、高扩展性以及良好的可用性。

Minio安装 (linux+docker)

bash 复制代码
//拉取镜像
docker pull quay.io/minio/minio

// 创建数据存储目录
mkdir -p ~/minio/data

// 创建minio
docker run -p 9001:9000 -p 9090:9090 --name minio --restart=always -v ~/minio/data:/data -e "MINIO_ROOT_USER=admin" -e "MINIO_ROOT_PASSWORD=yourpassword." -d quay.io/minio/minio server /data --console-address ":9090"
  • 参数解析
  1. docker run 运行容器

    启动一个新的 Docker 容器,如果镜像不存在,会自动拉取。

  2. -p 9001:9000 -p 9090:9090(端口映射)

    • -p 9001:9000

    • 将容器内部的 9000 端口 映射到 宿主机的 9001 端口,9000 是 MinIO 的 API 访问端口。

    • 这意味着你可以通过 http://localhost:9001 访问 MinIO 的 API。

    • -p 9090:9090

    • 将 容器内部的 9090 端口 映射到 宿主机的 9090 端口,9090 是 MinIO 的 Web 管理控制台端口。

    • 你可以通过 http://localhost:9090 访问 MinIO 的管理界面。

  3. --name minio(容器名称)

    • --name minio 给该容器命名为 minio,这样之后可以通过 docker stop minio / docker start minio 来管理它,而不需要使用容器 ID。

  4. --restart=always(自动重启)

    • --restart=always 让容器 始终自动重启,包括:

    • Docker 进程重启后,容器也会自动重启。

    • 容器异常退出时,Docker 也会自动重启它。

    • 但如果你 手动停止容器 (docker stop minio),它不会重启。

  5. -v ~/minio/data:/data(数据持久化)

    • -v ~/minio/data:/data 挂载数据卷,把 宿主机 ~/minio/data 目录映射到 容器内 /data 目录:

    • 这样 MinIO 存储的数据不会随着容器删除而丢失。

    • ~/minio/data 目录存储 MinIO 内部的对象数据。

  6. -e "MINIO_ROOT_USER=admin"(环境变量)

    • -e 传递环境变量,设置 MinIO 的 管理员用户名 为 admin。

  7. -e "MINIO_ROOT_PASSWORD=yourpassword."(环境变量)

    • 设定 MinIO 管理员密码 为 自己设置.。

  8. -d quay.io/minio/minio(后台运行 & 指定镜像)

    • -d 让容器 后台运行(detach mode)。

    quay.io/minio/minio 指定 MinIO 官方镜像(托管在 quay.io,类似于 docker.io)。

  9. server /data --console-address ":9090"(启动 MinIO 服务器)

    • server /data 指定 MinIO 使用 /data 目录 作为存储路径(前面 -v ~/minio/data:/data 绑定的目录)。

    • --console-address ":9090" 设置 MinIO Web 管理控制台 监听 9090 端口。

登录并创建桶

1、登录
2、创建桶


3、设置权限


在springBoot中使用 后端

1、导入坐标
xml 复制代码
<dependency>
    <groupId>io.minio</groupId>
    <artifactId>minio</artifactId>
    <version>8.5.2</version>
</dependency>
2、controller
java 复制代码
@RestController
@RequestMapping("/admin/system")
public class FileUploadController {

    @Autowired
    private FileUploadService fileUploadService;
    @PostMapping("/upload")
    //MultipartFile file 这个名字要和前端的name对应上. 我用的是element plus 默认的名字就是file
    public Result<String> fileUpload(MultipartFile file){
        //最后返回的是文件minio文件预览的浏览器的路径, 给前端作回显用
        // 见下面的我标红的图像
        String fileUrl=fileUploadService.fileUpload(file);
        return Result.build(fileUrl, ResultCodeEnum.SUCCESS);
    }
}
  • 返回的fileUrl 就是我标红的路径, 就是文件上传到的真实地方,方便前端作回显示
  • 如果你用的不是Element plus 作上传, 记得名字要匹配了. 这里都是属于SpringMVC的知识 , 变量的名字都一样不要 @RequestParm 注解也行
html 复制代码
<form id="uploadForm">
    <input type="file" name="file"> <!-- 这里的 name="file" 要和 @RequestParam("file") 一致 -->
    <button type="button" onclick="uploadFile()">上传</button>
</form>
3、service
java 复制代码
@Service
public class FileUploadServiceImpl implements FileUploadService {

    //使用配置文件的方式读,minio的配置, 不硬编码
    @Autowired
    private MinioProperties minioProperties;
    @Override
    public String fileUpload(MultipartFile file) {
        String fileUrl= null;
        try {
            MinioClient  minioClient =
                    MinioClient.builder()
                            .endpoint(minioProperties.getEndpointUrl())  // MinIO 服务器地址
                            .credentials(minioProperties.getAccessKey(), //  账号
                                    minioProperties.getSecureKey()) //密码
                            .build();

            // 不存在桶就创建
            boolean found =
                    minioClient.bucketExists(BucketExistsArgs.builder().bucket(minioProperties.getBucketName()).build());
//                不能用下滑线连接,拼接访问路径会出错
            if (!found) {
                // 创建
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(minioProperties.getBucketName()).build());
            }
            //创建日期文件夹
            //DataUtil 来自Hutool工具类库
            String path = DateUtil.format(new Date(), "yyyyMMdd");
            //生成随机文件名
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            String fileName=path+'/'+uuid+file.getOriginalFilename();

            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(minioProperties.getBucketName())  //桶名称
                            .object(fileName)  //文件名
                            // 采用的是已经知道文件大小的读     -1 表示 不限制分块大小(自动选择最佳方式)
                            .stream(file.getInputStream(), file.getSize(), -1)
                            //设置 文件的 MIME 类型)
                            //让 MinIO 知道如何处理和预览这个文件。
                            .contentType(file.getContentType())
                            .build());
            //手动拼接url,给前端,方便前端作回显示
            fileUrl = minioProperties.getEndpointUrl()+"/"+minioProperties.getBucketName()+'/'+fileName;
        } catch (Exception e) {
            e.printStackTrace();
        }
        //我们是在新增用户的时候给用户添加头像的,你给前端访问路径了, 前端会映射到头像(avator这个字段上), 一点击新增用户,直接就把这个url带到mysql中了, 所有这里就不用写mapper了
        return fileUrl;
    }
}
  • 其中 用到DataUtil工具类,需要导入hutool
xml 复制代码
<!--        生成验证码 ,日期时间等-->
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.5.2</version>
        </dependency>
4、 配置文件内容

在配置文件中添加Minio的相关配置

yaml 复制代码
# 自定义配置
spzx:
  minio:
   # 别用https,如果你没有申请过ssl证书,就http就可以
   # 用户名和密码都是 在docker构建 minio的时候设置的
    endpointUrl: http://服务器ip:9000      
    accessKey: 你的用户名
    secreKey: 你设置的密码
    bucketName: 给桶起个名字
5、 MinioProperties读配置文件

将构建MinioClient所对应的参数定义到配置文件中,然后通过该实体类封装该配置文件中的内容.

java 复制代码
@Data // 需要提供get方法
@ConfigurationProperties(prefix = "spzx.minio")
public class MinioProperties {
//和yml声明的属性保持一致
    private String endpointUrl;  // minio的url
    private String accessKey;  //账号
    private String secureKey;// 密码
    private String bucketName; //桶的名字
}
  • 记得在启动类中 加上@EnableConfigurationProperties
java 复制代码
@SpringBootApplication
@ComponentScan(basePackages = {"com.chen"})
// 让spring能扫到我们自己写的配置类
@EnableConfigurationProperties(value = {MinioProperties.class})
public class SpzxManagerApplication {
    public static void main(String[] args) {
       SpringApplication.run(SpzxManagerApplication.class,args);
    }
}

前端 vue

html 复制代码
<template>
	<el-form-item label="头像">
	        <!--         element plus     默认上传的name就是file, 和你controller启的名字对应上 -->
	        <el-upload
	            class="avatar-uploader"
	            action="http://localhost:8501/admin/system/upload"
	            :show-file-list="false"
	            :headers="headers"
	            :on-success="loadSuccess"
	        >
	          <img v-if="sysUser.avatar" :src="sysUser.avatar" class="avatar"/>
	          <el-icon v-else class="avatar-uploader-icon">
	            <Plus/>
	          </el-icon>
	        </el-upload>
	      </el-form-item>
</template>	      
js 复制代码
//定义用户数据模型
const defaultSysUserForm = {
  id: '',
  userName: "",
  password: "",
  name: "",
  phone: "",
  avatar: "",   // 操作用户的头像
  description: ""
}
const sysUser = ref(defaultSysUserForm)
//上传成功的回调函数
const loadSuccess = (response) => {
  //这里response 就是我们后端封装的 result对象
  //给响应式对象复制
  //loadSuccess(response) 是上传成功的回调函数
  // response.data 包含上传成功后的文件 URL(即头像地址)。
  // 这样 sysUser.value.avatar 就能保存 新头像的 URL,从而在前端显示最新上传的头像。
  sysUser.value.avatar = response.data
}
相关推荐
舒一笑2 分钟前
🚀 PandaCoder 2.0.0 - ES DSL Monitor & SQL Monitor 震撼发布!
后端·ai编程·intellij idea
Java中文社群5 分钟前
服务器被攻击!原因竟然是他?真没想到...
java·后端
Full Stack Developme17 分钟前
java.nio 包详解
java·python·nio
零千叶33 分钟前
【面试】Java JVM 调优面试手册
java·开发语言·jvm
代码充电宝42 分钟前
LeetCode 算法题【简单】290. 单词规律
java·算法·leetcode·职场和发展·哈希表
li3714908901 小时前
nginx报400bad request 请求头过大异常处理
java·运维·nginx
摇滚侠1 小时前
Spring Boot 项目, idea 控制台日志设置彩色
java·spring boot·intellij-idea
helloworddm1 小时前
Orleans 流系统握手机制时序图
后端·c#
Aevget2 小时前
「Java EE开发指南」用MyEclipse开发的EJB开发工具(二)
java·ide·java-ee·eclipse·myeclipse
黄昏晓x2 小时前
C++----多态
java·jvm·c++