MinIO官方文档
http://docs.minio.org.cn/docs/master/minio-multi-user-quickstart-guide
1.拉取MinIO的Docker镜像
docker pull minio/minio
2.在Docker容器中运行MinIO,这里我们将MiniIO的数据和配置文件夹挂在到宿主机上
docker run -p 9000:9000 --name minio \
-d --restart=always \
-e "MINIO_ACCESS_KEY=admin" \
-e "MINIO_SECRET_KEY=admin123456" \
-v /home/data:/data \
-v /home/config:/root/.minio \
minio/minio server /data
/home/data--这个路径会指定桶的路径
MINIO_ACCESS_KEY 是登录名
MINIO_SECRET_KEY 是密码
访问地址http://服务器ip:9000/minio 默认端口9000 注意:修改端口需要修改容器里面的端口
3.springclould集成minio
添加maven依赖
io.minio minio 7.1.0
3.1 yml文件配置
minio:
url: http://服务器ip:9000
accessKey: admin
secretKey: admin123456
bucketName: saas-test
3.2 代码初始化minio配置
package com.cecport.saas.api.properties.minio;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "minio")
public class MinIoProperties {
/**
* minio地址+端口号
*/
private String url;
/**
* minio用户名
*/
private String accessKey;
/**
* minio密码
*/
private String secretKey;
/**
* 文件桶的名称
*/
private String bucketName;
}
package com.cecport.saas.common.minio.config;
import com.cecport.saas.api.properties.minio.MinIoProperties;
import io.minio.MinioClient;
import io.minio.messages.Bucket;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.List;
@Slf4j
@Component
public class MinIoConfig {
private static MinioClient minioClient;
@Autowired
private MinIoProperties minIoProperties;
/**
* @author yanghui
* @description: 获取minioClient
* @date 2021/6/22 16:55
* @return io.minio.MinioClient
*/
public static MinioClient getMinioClient(){
return minioClient;
}
/**
* 判断 bucket是否存在
*
* @param bucketName:
* 桶名
* @return: boolean
* @date : 2020/8/16 20:53
*/
@SneakyThrows(Exception.class)
public static boolean bucketExists(String bucketName) {
return minioClient.bucketExists(bucketName);
}
/**
* 获取全部bucket
*
* @param :
* @return: java.util.List
* @date : 2020/8/16 23:28
*/
@SneakyThrows(Exception.class)
public static List getAllBuckets() {
return minioClient.listBuckets();
}
/**
* 初始化minio配置
*
* @param :
* @return: void
* @date : 2020/8/16 20:56
*/
@PostConstruct
public void init() {
try {
minioClient = new MinioClient(minIoProperties.getUrl(), minIoProperties.getAccessKey(),
minIoProperties.getSecretKey());
createBucket(minIoProperties.getBucketName());
} catch (Exception e) {
e.printStackTrace();
log.error("初始化minio配置异常: 【{}】", e.fillInStackTrace());
}
}
}
3.3 编写一个工具类
package com.cecport.saas.common.minio.util;
import com.cecport.saas.common.minio.config.MinIoConfig;
import com.cecport.saas.util.base.Result;
import com.sun.org.apache.regexp.internal.RE;
import io.minio.GetObjectArgs;
import io.minio.MinioClient;
import io.minio.PutObjectOptions;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
@Slf4j
@Component
public class MinIoUtils {
/**
* Minio文件上传
*
* @param file 文件实体
* @param fileName 修饰过的文件名 非源文件名
* @param bucketName 所存文件夹(桶名)
* @return
*/
public Result minioUpload(MultipartFile file, String fileName, String bucketName) {
try {
MinioClient minioClient = MinIoConfig.getMinioClient();
// fileName为空,说明要使用源文件名上传
if (fileName == null) {
fileName = file.getOriginalFilename();
fileName = fileName.replaceAll(" ", "_");
}
InputStream inputStream = file.getInputStream();
// minio仓库名
//minioClient.putObject(bucketName, fileName, file.getInputStream(), file.getContentType());
minioClient.putObject(bucketName, fileName, inputStream, new PutObjectOptions(inputStream.available(), -1));
log.info("成功上传文件 " + fileName + " 至 " + bucketName);
String fileUrl = bucketName + "/" + fileName;
Map map = new HashMap(3);
map.put("fileUrl", fileUrl);
map.put("bucketName", bucketName);
map.put("originFileName", fileName);
return Result.ok(map);
} catch (Exception e) {
e.printStackTrace();
if (e.getMessage().contains("ORA")) {
return Result.error("上传失败:【查询参数错误】");
}
return Result.error("上传失败:【" + e.getMessage() + "】");
}
}
/**
* 判断文件是否存在
*
* @param fileName 文件名
* @param bucketName 桶名(文件夹)
* @return
*/
public boolean isFileExisted(String fileName, String bucketName) {
InputStream inputStream = null;
try {
MinioClient minioClient = MinIoConfig.getMinioClient();
inputStream = minioClient.getObject(bucketName, fileName);
if (inputStream != null) {
return true;
}
} catch (Exception e) {
return false;
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return false;
}
/**
* 删除文件
*
* @param bucketName 桶名(文件夹)
* @param fileName 文件名
* @return
*/
public boolean delete(String bucketName, String fileName) {
try {
MinioClient minioClient = MinIoConfig.getMinioClient();
minioClient.removeObject(bucketName, fileName);
return true;
} catch (Exception e) {
log.error(e.getMessage());
return false;
}
}
/**
* 下载文件
*
* @param objectName 文件名
* @param bucketName 桶名(文件夹)
* @param response
* @return
*/
public Result downloadFile(String objectName, String bucketName, HttpServletResponse response) {
try {
MinioClient minioClient = MinIoConfig.getMinioClient();
InputStream file = minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
if (Objects.isNull(file)){
return Result.error("文件不存在");
}
String filename = new String(objectName.getBytes("ISO8859-1"), StandardCharsets.UTF_8);
response.setHeader("Content-Disposition", "attachment;filename=" + filename);
ServletOutputStream servletOutputStream = response.getOutputStream();
int len;
byte[] buffer = new byte[1024];
while ((len = file.read(buffer)) > 0) {
servletOutputStream.write(buffer, 0, len);
}
servletOutputStream.flush();
file.close();
servletOutputStream.close();
return Result.ok(objectName + "下载成功");
} catch (Exception e) {
e.printStackTrace();
if (e.getMessage().contains("ORA")) {
return Result.error("下载失败:【查询参数错误】");
}
return Result.error("下载失败:【" + e.getMessage() + "】");
}
}
/**
* 获取文件流
*
* @param objectName 文件名
* @param bucketName 桶名(文件夹)
* @return
*/
public InputStream getFileInputStream(String objectName, String bucketName) {
try {
MinioClient minioClient = MinIoConfig.getMinioClient();
return minioClient.getObject(bucketName, objectName);
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage());
}
return null;
}
/**
* @author yanghui
* @description: 创建桶
* @date 2021/7/20 13:51
* @param bucketName:
*/
public void createBucketName(String bucketName) {
try {
if (StringUtils.isBlank(bucketName)){
return;
}
MinioClient minioClient = MinIoConfig.getMinioClient();
boolean isExist = minioClient.bucketExists(bucketName);
if(isExist) {
log.info("Bucket {} already exists.", bucketName);
} else {
minioClient.makeBucket(bucketName);
}
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage());
}
}
/**
* @author yanghui
* @description: 删除桶
* @date 2021/7/20 13:51
* @param bucketName:
*/
public void deleteBucketName(String bucketName) {
try {
if (StringUtils.isBlank(bucketName)){
return;
}
MinioClient minioClient = MinIoConfig.getMinioClient();
boolean isExist = minioClient.bucketExists(bucketName);
if(isExist) {
minioClient.removeBucket(bucketName);
}
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage());
}
}
/**
* @author yanghui
* @description: 删除桶下面所有文件
* @date 2021/7/20 13:51
* @param bucketName:
*/
public void deleteBucketFile(String bucketName) {
try {
if (StringUtils.isBlank(bucketName)){
return;
}
MinioClient minioClient = MinIoConfig.getMinioClient();
boolean isExist = minioClient.bucketExists(bucketName);
if(isExist) {
minioClient.deleteBucketLifeCycle(bucketName);
}
} catch (Exception e) {
e.printStackTrace();
log.error(e.getMessage());
}
}
}
以上步骤做完 minio集成springboot就实现
1.需要安装MinIO Client (mc) 及配置minio服务
2.官方下载地址:https://dl.min.io/client/mc/release/linux-amd64/mc
3.下载的的文件放到自己想要的目录下,我放在/usr/local/mc/
文件夹下
4. 给文件授权可执行权限:sudo chmod +x /usr/local/mc/mc
5.进入mc目录下,执行./mc
看是否成功 网上说初次执行会生成目录 /root/.mc
我执行玩之后生成的目录是在/home/admin/.mc 下面的图可以看到默认路径
5.1以下是默认生成的配置文件信息
5.2通过如下命令 ./mc config host list:查看主机的mc配置
6.给local创建别名为sxdb,用户名密码为admin admin123456 minio.service配置文件配置的用户名和密码 也是我们默认的管理员密码
./mc config host add sxdb http://localhost:9000 admin admin123456
6.1再执行一下./mc config host list查看mc配置,可以看到新增了一条
7创建自定义策略配置文件 getonly.json
touch getonly.json
{
"Version": "2012-10-17", #这个日期是官方文档提供的日期 算默认吧
"Statement": [
{
"Effect": "Allow",
"Action": [ // 权限列表
"s3:ListAllMyBuckets", // 查看所有的桶权限
"s3:ListBucket", // 查看桶内对象权限
"s3:GetBucketLocation", // 定位bucket权限
"s3:GetObject", // 下载权限
"s3:PutObject", // 上传权限
"s3:DeleteObject" // 删除权限
],
"Resource": [
"arn:aws:s3:::saas-test/*" // arn:aws:s3不用动,后面用*表示所有桶,用onebucket/*表示只针对这个桶
]
}
]
}
8.给策略别名sxdb添加自定义策略配置:./mc admin policy add sxdb getonlygetonly.json
./mc admin policy list sxdb 可以看到默认readonly,readwrite,writeonly三个权限
可以看到我们添加的策略
9.添加用户 mc admin user add myminio newuser newuser123
10.给用户设置访问策略 mc admin policy set sxdb getonly user=newuser
11.如果有更改策略配置json文件,则可以重新执行如下命令:
mc admin policy add sxdb getonly getonly.json
12.使用管理员创建多个桶 我们之前给saas-test设置了权限
13.换自己创建的用户newuser newuser123登录,进行上传,删除操作
newuser只能看到一个桶的数据
当我们进行上传文件的时候 会提示没有上传权限
可以更改权限配置文件把删除的权限去掉,添加上传权限
在重新加载策略就可以实现上传权限了
重新执行命令,重新加载命令:mc admin policy add sxdb getonly getonly.json