说明:Minio是开源的对象存储服务器,相当于免费版的OSS,本文介绍在Linux环境下部署Minio服务器,并在SpringBoot中使用,最后将Minio的代码打包成一个起步依赖。
首先,在官网上下载服务器程序,非常简单,下载下来就是一个文件;
这里建议不要使用命令行的方式直接在服务器上输入 wget https://dl.min.io/server/minio/release/linux-amd64/minio
下载,网络环境不好,巨慢;
下载完成后,是一个没有扩展名的文件,上传到云服务器上,在根目录下创建一个minio文件夹,把服务器程序放到这个文件夹里面;
输入下面两行命令,启动minio服务器;
chmod +x minio
MINIO_ROOT_USER=admin MINIO_ROOT_PASSWORD=password ./minio server /mnt/data --console-address ":9001"
第一行命令:给minio文件设置可执行权限;
第二行命令:设置minio服务器的账号(admin)、密码(password),并启动,端口是9001;
注意密码位数不要过少,会启动失败,使用默认的就可以;
启动完成后,就可以通过IP:端口
的方式来访问了。需要注意,如果使用的是云服务器,需要开放9001端口;
在页面中输入地址,访问到minio的管理平台;
如果有使用过OSS,就会非常熟悉这些界面上的操作;
创建一个桶,设置为public
,后面在代码中使用;
创建完bucket后,可以直接把文件资源上传到Minio上;
首先,创建一个简单的SpringBoot项目,只加入下面两个依赖,pom文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.hzygroupId>
<artifactId>minio-simpleartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<maven.compiler.source>11maven.compiler.source>
<maven.compiler.target>11maven.compiler.target>
properties>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.7.12version>
<relativePath/>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>io.miniogroupId>
<artifactId>minioartifactId>
<version>8.4.3version>
dependency>
dependencies>
project>
创建Minio所需要的配置文件类,另外注入一个MinioClient对象到IOC容器中;
import io.minio.MinioClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
@ConfigurationProperties(prefix = "minio")
public class MinioConfig {
private String endpoint;
private String bucketName;
private String accessKey;
private String secretKey;
public String getEndpoint() {
return endpoint;
}
public void setEndpoint(String endpoint) {
this.endpoint = endpoint;
}
public String getBucketName() {
return bucketName;
}
public void setBucketName(String bucketName) {
this.bucketName = bucketName;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getSecretKey() {
return secretKey;
}
public void setSecretKey(String secretKey) {
this.secretKey = secretKey;
}
/**
* 创建一个Minio客户端
* @return
*/
@Bean
public MinioClient createMinioClient(){
return MinioClient
.builder()
.endpoint(endpoint)
.credentials(accessKey,secretKey)
.build();
}
}
创建一个Minio操作的工具类,如下,更多请参考(http://t.csdn.cn/hHfDK):
import com.hzy.config.MinioConfig;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
/**
* MinIO工具类
*/
@Component
@EnableConfigurationProperties(MinioConfig.class)
public class MinioUtils {
@Autowired
private MinioClient minioClient;
@Autowired
private MinioConfig minIOConfig;
/**
* 创建基于Java端的MinioClient
*/
public void createMinioClient() {
if (null == minioClient) {
minioClient = MinioClient
.builder()
.endpoint(minIOConfig.getEndpoint())
.credentials(minIOConfig.getAccessKey(), minIOConfig.getSecretKey())
.build();
try {
createBucket(minIOConfig.getBucketName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 启动SpringBoot容器的时候初始化Bucket
* 如果没有Bucket则创建
*
* @throws Exception
*/
private void createBucket(String bucketName) throws Exception {
if (!bucketExists(bucketName)) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
}
/**
* 判断Bucket是否存在,true:存在,false:不存在
*
* @return
* @throws Exception
*/
public boolean bucketExists(String bucketName) throws Exception {
return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
}
/**
* 使用MultipartFile进行文件上传
*
* @param bucketName 存储桶
* @param fileBytes 文件字节数组
* @param objectName 对象名
* @param contentType 类型
* @return
* @throws Exception
*/
public ObjectWriteResponse uploadFile(String bucketName, byte[] fileBytes, String objectName,
String contentType) throws Exception {
InputStream inputStream = new ByteArrayInputStream(fileBytes);
return minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.contentType(contentType)
.stream(inputStream, inputStream.available(), -1)
.build());
}
}
设置配置文件,如下,注意哦,Minio代码端连接的端口是9000,所以如果使用的是云服务器,需要开通此端口;
minio:
endpoint: http://Minio服务器IP:9000
bucketName: simple
accessKey: admin
secretKey: password
最后,创建一个Controller,启动,测试;
import com.hzy.utils.MinioUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
@RestController
public class MinioController {
@Autowired
private MinioUtils minioUtils;
@PostMapping("upload")
public void uploadImage(MultipartFile file){
try {
minioUtils.uploadFile("simple", file.getBytes(), "pic", file.getContentType());
} catch (Exception e) {
e.printStackTrace();
}
}
}
使用Apifox,填上地址、请求方式为POST、请求数据为Body,表单、参数名file(要与controller层一致)、选择文件;
发送完成后,查看Minio管理平台,查看文件;
可以看到,图片已上传成功;
这时,点击图片,右边有个Share
,点击,在弹出的窗口里可以看到该图片的连接;
但是注意哦,这个链接是假链接,无效的,将这个链接修改成如下才可以访问到图片:
http://Minio服务器IP:9000/bucket名/文件路径
如果敲完回车,没有图片,而提示下面的信息,需要 检查一下你的bucket是不是public(公开的)
而这个路径,我们是可以在代码里拼接的,比如上传图片后我们需要将此地址存入到数据库中,就可以将代码改成下面这样:
@RestController
public class MinioController {
@Autowired
private MinioUtils minioUtils;
@Autowired
private MinioConfig minioConfig;
@PostMapping("upload")
public String uploadImage(MultipartFile file) {
// 生成UUID作为文件的名称
String fileName = UUID.randomUUID() + file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf('.'));
try {
// 上传到Minio上
minioUtils.uploadFile(minioConfig.getBucketName(), file.getBytes(), fileName, file.getContentType());
} catch (Exception e) {
e.printStackTrace();
}
// 文件的路径,可存入数据库
return minioConfig.getEndpoint() + "/" + minioConfig.getBucketName() + "/" + fileName;
}
}
发送图片测试;
打开这个链接,可以访问到这张图片;
当然,这还是非常粗糙的,在项目中使用需要考虑到图片大小和格式校验、目录分级、图片审核等等;
首先,先另外创建一个SpringBoot项目,用来测试Minio起步依赖,pom文件如下:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.hzygroupId>
<artifactId>starter-simpleartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<maven.compiler.source>11maven.compiler.source>
<maven.compiler.target>11maven.compiler.target>
properties>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.7.12version>
<relativePath/>
parent>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>com.hzygroupId>
<artifactId>minio-simpleartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
dependencies>
project>
把前面Minio项目中的controller层代码、application.yml配置都剪切过来,如下:
Minio作为起步依赖,为了方别其他模块引用使用,原则是尽可能少的引用其他依赖,降低其他模块使用的成本,所以需要进行一些裁剪;
那么,如果不太清楚该去掉哪些依赖,我的一个方法是,先去掉依赖,然后根据报错的注解,再按提示添加对应的依赖,这样可以尽可能少的添加依赖。
(去掉Minio-simple项目中的parent标签的内容,代码报错,依据提示添加依赖)
按照提示,minio-simple项目加入以下依赖即可
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.hzygroupId>
<artifactId>minio-simpleartifactId>
<version>1.0-SNAPSHOTversion>
<properties>
<maven.compiler.source>11maven.compiler.source>
<maven.compiler.target>11maven.compiler.target>
properties>
<dependencies>
<dependency>
<groupId>io.miniogroupId>
<artifactId>minioartifactId>
<version>8.4.3version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.3.27version>
<scope>compilescope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-bootartifactId>
<version>2.7.12version>
<scope>compilescope>
dependency>
dependencies>
project>
改造完成后,强烈建议启动starter-simple项目(demo项目),测试一下功能是否还能跑通;
在minio-simple项目中的Maven中,跳过test,执行install命令,安装此项目到本地仓库中;
执行完成;
此时,可以在本地仓库中找到此Maven;
最后一步,也是最重要的一步,测试该起步依赖是否整合成功。
首先,需要把前面的minio-simple项目移除项目空间,有些同学忽略了此步骤,测试成功后就认为起步依赖整合完成了,其实不是哈,这样子使用的仍然是minio-simple项目中的代码,而不是本地仓库的jar包;
确认一下,pom.xml中添加了Minio起步依赖的Maven坐标;
启动项目;
测试完成;
至此,Minio起步依赖整合完成,以后别的项目中,可以直接在项目中引入该依赖,自动装配对应的Bean对象,使用对应的方法;
Minio与OSS差不多,但是开源、免费,推荐使用;