Minio整合SpringBoot


POM:
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>7.1.0</version>
</dependency>
yml文件配置(注意层级):
minio:
bucket: "桶名"
host: "http://192.168.1.123:5000"
url: "${minio.host}/${minio.bucket}/"
access-key: 用户名
secret-key: 密码
将MinioClient作为Bean加入容器管理
import io.minio.*;
import io.minio.errors.*;
import io.minio.messages.Item;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.pdfbox.io.MemoryUsageSetting;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile; import java.io.*;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List; import static io.minio.ErrorCode.NO_SUCH_KEY;
import static io.minio.http.Method.GET; @Component
public class MinioHelper { @Value(value = "${minio.bucket}")
private String bucket; @Value(value = "${minio.host}")
private String host; @Value(value = "${minio.url}")
private String url; @Value(value = "${minio.access-key}")
private String accessKey; @Value(value = "${minio.secret-key}")
private String secretKey; @Autowired
private MinioClient minioClient; @Bean
public MinioClient getMinioClient() {
MinioClient minioClient=MinioClient.builder()
.endpoint(host).credentials(accessKey,secretKey).build();
log.info("minioClient init success.");
return minioClient;
}
private final Logger log = LoggerFactory.getLogger(MinioHelper.class); /**
* 根据名字获得返回类型
* @param fileName
* @return
* @throws Exception
*/
public ObjectStat getStat(String fileName) throws Exception {
ObjectStat stat = minioClient.statObject(StatObjectArgs.builder()
.bucket(bucket).object(fileName).build());
return stat;
} /**
*上传文件到桶中
* @param multipartFile
* @param directory should be end with / or ""
* @return
* @throws IOException
* @throws InvalidKeyException
* @throws ErrorResponseException
* @throws IllegalArgumentException
* @throws InsufficientDataException
* @throws InternalException
* @throws InvalidBucketNameException
* @throws InvalidResponseException
* @throws NoSuchAlgorithmException
* @throws XmlParserException
* @throws RegionConflictException
* @throws ServerException
*/
public String putObject(MultipartFile multipartFile, String directory) throws
IOException, InvalidKeyException, ErrorResponseException, IllegalArgumentException,
InsufficientDataException, InternalException, InvalidBucketNameException, InvalidResponseException,
NoSuchAlgorithmException, XmlParserException, RegionConflictException, ServerException {
log.debug("start upload file .");
this.createBucket(minioClient, bucket);
String fileName = multipartFile.getOriginalFilename();
String rename = "";
log.debug("Upload File name is:" + fileName);
if (StringUtils.isNotEmpty(directory)) {
rename = renameFileVersion(directory + "/" + fileName, minioClient);
} else {
rename = renameFileVersion(fileName, minioClient);
}
try (InputStream inputStream = multipartFile.getInputStream()) {
minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(rename).
contentType(multipartFile.getContentType()).
stream(inputStream, multipartFile.getSize(), -1).build());
inputStream.close();
return rename;
}
} /**
* 获取文件的InputStream流对象
* @param fileUri format : directory/filename,filename must contains filetype,like xxx.pdf
* @throws IOException
* @throws InvalidKeyException
* @throws IllegalArgumentException
* @throws NoSuchAlgorithmException
*/
public InputStream getFileInputStream(String fileUri) throws
IOException, InvalidKeyException,IllegalArgumentException, NoSuchAlgorithmException {
log.debug("start get file IO.");
InputStream input=null;
try {
input=minioClient.getObject(GetObjectArgs.builder().bucket(bucket).object(fileUri).build());
} catch(MinioException e) {
log.debug("Error occurred: " + e.getMessage());
}
return input;
} /**
*在桶下创建文件夹,文件夹层级结构根据参数决定
* @param WotDir should be end with /
* @return
* @throws IOException
* @throws InvalidKeyException
* @throws InvalidResponseException
* @throws InsufficientDataException
* @throws NoSuchAlgorithmException
* @throws InternalException
* @throws XmlParserException
* @throws InvalidBucketNameException
* @throws ErrorResponseException
* @throws RegionConflictException
* @throws ServerException
*/
public String createDirectory(String WotDir) throws IOException, InvalidKeyException,
InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException,
InternalException, XmlParserException, InvalidBucketNameException,
ErrorResponseException, RegionConflictException, ServerException {
log.debug("start create directory.");
this.createBucket(minioClient,bucket);
minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(WotDir).stream(
new ByteArrayInputStream(new byte[] {}), 0, -1)
.build());
log.debug("Create a new Directory:"+WotDir);
return WotDir;
} /**
* 获取文件的下载url
* @param fileUri
* @return
* @throws IOException
* @throws InvalidKeyException
* @throws InvalidResponseException
* @throws InsufficientDataException
* @throws NoSuchAlgorithmException
* @throws ServerException
* @throws InternalException
* @throws XmlParserException
* @throws InvalidBucketNameException
* @throws ErrorResponseException
* @throws RegionConflictException
* @throws InvalidExpiresRangeException
*/ public String getDownloadUrl(String fileUri) throws IOException, InvalidKeyException,
InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException,
ServerException,InternalException, XmlParserException, InvalidBucketNameException,
ErrorResponseException, RegionConflictException,
InvalidExpiresRangeException {
log.debug("start get url for download.");
this.createBucket(minioClient,bucket);
//Use Get Method
String fileurl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(this.bucket).object(fileUri).method(GET).build());
log.debug("You can download file through this url:"+fileurl);
return fileurl;
} /**
*该方法用于更新文档,
* @param multipartFile
* @param orderNum
* @return 是Minio中的Object名
* @throws IOException
* @throws InvalidKeyException
* @throws ErrorResponseException
* @throws IllegalArgumentException
* @throws InsufficientDataException
* @throws InternalException
* @throws InvalidBucketNameException
* @throws InvalidResponseException
* @throws NoSuchAlgorithmException
* @throws XmlParserException
* @throws RegionConflictException
* @throws ServerException
*/
public String uploadFileWithArgsForApp(MultipartFile multipartFile,String orderNum,String fileName) throws
IOException, InvalidKeyException, ErrorResponseException, IllegalArgumentException,
InsufficientDataException, InternalException, InvalidBucketNameException, InvalidResponseException,
NoSuchAlgorithmException, XmlParserException, RegionConflictException, ServerException {
log.debug("start upload file .");
this.createBucket(minioClient,bucket);
log.debug("Upload File name is:"+fileName);
String rename=orderNum+"/"+fileName;
try (InputStream inputStream = multipartFile.getInputStream()) {
minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(rename).
contentType(multipartFile.getContentType()).
stream(inputStream,multipartFile.getSize(),-1).build());
return rename;
}
} public String getloadUrl(String fileUri) throws IOException, InvalidKeyException,
InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException,
ServerException,InternalException, XmlParserException, InvalidBucketNameException,
ErrorResponseException, RegionConflictException,
InvalidExpiresRangeException {
log.debug("start get url for download.");
this.createBucket(minioClient,bucket);
//Use Get Method
String fileurl = minioClient.getObjectUrl(bucket,fileUri);
log.debug("You can download file through this url:"+fileurl);
return fileurl;
} /**
* 批量下载
* @param directory
* @return
* @throws IOException
* @throws InvalidKeyException
* @throws InvalidResponseException
* @throws InsufficientDataException
* @throws NoSuchAlgorithmException
* @throws ServerException
* @throws InternalException
* @throws XmlParserException
* @throws InvalidBucketNameException
* @throws ErrorResponseException
* @throws InvalidExpiresRangeException
*/
public List<String> downLoadMore(String directory) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException, InvalidExpiresRangeException {
Iterable<Result<Item>> objs = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucket).prefix(directory).useUrlEncodingType(false).build());
List<String> list =new ArrayList<>();
for (Result<Item> result : objs) {
String objectName = null;
objectName = result.get().objectName();
ObjectStat statObject = minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(objectName).build());
if (statObject != null && statObject.length() > 0) {
String fileurl = minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder().bucket(this.bucket).object(statObject.name()).method(GET).build());
list.add(fileurl);
}
}
return list;
} /**
* 刪除文件
* @param fileUri
* @return
* @throws IOException
* @throws InvalidKeyException
* @throws InvalidResponseException
* @throws InsufficientDataException
* @throws NoSuchAlgorithmException
* @throws ServerException
* @throws InternalException
* @throws XmlParserException
* @throws InvalidBucketNameException
* @throws ErrorResponseException
*/
public String removeFile(String fileUri) throws IOException, InvalidKeyException, InvalidResponseException,
InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException,
InvalidBucketNameException, ErrorResponseException {
log.debug("Start remove File :"+fileUri);
ObjectStat objectStat = minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(fileUri).build());
minioClient.removeObject(RemoveObjectArgs.builder().bucket(bucket).object(fileUri).build());
log.debug("File has been removed");
return fileUri; } /**
* 合并PDF
* @param files
* @param dir
* @return
* @throws NoSuchAlgorithmException
* @throws InvalidKeyException
* @throws IOException
* @throws InsufficientDataException
* @throws InternalException
* @throws InvalidResponseException
* @throws InvalidBucketNameException
* @throws XmlParserException
* @throws ServerException
* @throws ErrorResponseException
*/
public String mergeFile(List<String> files, String dir,String name) throws NoSuchAlgorithmException, InvalidKeyException, IOException, InsufficientDataException, InternalException, InvalidResponseException, InvalidBucketNameException, XmlParserException, ServerException, ErrorResponseException {
OutputStream outputStream = new ByteArrayOutputStream();
PDFMergerUtility merger = new PDFMergerUtility();
merger.setDestinationStream(outputStream);
for (String s:files
) {
InputStream in = this.getFileInputStream(s);
merger.addSource(in);//添加所有文件的输入流对象
}
merger.mergeDocuments(MemoryUsageSetting.setupMainMemoryOnly());
log.debug("Merge File Stream success" );
ByteArrayOutputStream baos = (ByteArrayOutputStream) merger.getDestinationStream();
ByteArrayInputStream swapStream = new ByteArrayInputStream(baos.toByteArray());
MultipartFile multipartFile = new MockMultipartFile(name+".pdf", name+".pdf", "application/pdf", IOUtils.toByteArray(swapStream));
log.debug("Merge upload File has been create" );
String fileName = multipartFile.getOriginalFilename();
String rename = dir+"/"+fileName;
try (InputStream inputStream = multipartFile.getInputStream()) {
minioClient.putObject(PutObjectArgs.builder().bucket(bucket).object(rename).
contentType(multipartFile.getContentType()).
stream(inputStream, multipartFile.getSize(), -1).build());
inputStream.close();
return rename;
} } /**
* 重命名
* @param objectName
* @param minioClient
* @return
* @throws IOException
* @throws InvalidKeyException
* @throws InvalidResponseException
* @throws InsufficientDataException
* @throws NoSuchAlgorithmException
* @throws ServerException
* @throws XmlParserException
* @throws InvalidBucketNameException
* @throws InternalException
* @throws ErrorResponseException
*/
private String renameFileVersion(String objectName,MinioClient minioClient) throws IOException, InvalidKeyException
, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, XmlParserException,
InvalidBucketNameException, InternalException, ErrorResponseException {
log.debug("start rename file.");
boolean flag =false;
int i=2;
StringBuffer temp = new StringBuffer(objectName.substring(0, objectName.length() - 4));
String result = objectName;
String sufix = objectName.substring(objectName.length() - 4);
String version = objectName.substring(objectName.length() - 7,objectName.length() - 4);
if(version.startsWith("_V")){//存在有版本号的,非初始版本
do{
try {
ObjectStat objectStat = minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(result).build());
temp=new StringBuffer(objectName.substring(0, objectName.length() - 7));
temp.append("_V"+i+sufix);
result = temp.toString();
i++;
flag = true;
} catch (ErrorResponseException e) {
if(e.errorResponse().errorCode().equals(NO_SUCH_KEY)){
flag=false;
}else throw e ;
}
}while (flag);
}else{
do{
try {
ObjectStat objectStat = minioClient.statObject(StatObjectArgs.builder().bucket(bucket).object(result).build());
//每次上传的版本不能低于上一个版本
//第一次上传不加版本号
//第二次上传为v2,依次叠加,后续上传规则变更,另作修改
if (i>2){
temp=new StringBuffer(objectName.substring(0, objectName.length() - 4));
}
temp.append("_V"+i+sufix);
result = temp.toString();
i++;
flag = true;
} catch (ErrorResponseException e) {
if(e.errorResponse().errorCode().equals(NO_SUCH_KEY)){
flag=false;
}else throw e ;
}
}while (flag);
} return result;
}
/*创建桶*/
private void createBucket(MinioClient minioClient,String bucket) throws IOException, InvalidKeyException, InvalidResponseException, InsufficientDataException, NoSuchAlgorithmException, ServerException, InternalException, XmlParserException, InvalidBucketNameException, ErrorResponseException, RegionConflictException {
if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucket).build())) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
log.debug("Create a new Bucket:"+bucket);
}else{
log.debug("Bucket has been exisit:"+bucket);
}
}
}

Minio整合SpringBoot的更多相关文章

  1. 整合springboot(app后台框架搭建四)

    springboot可以说是为了适用SOA服务出现,一方面,极大的简便了配置,加速了开发速度:第二方面,也是一个嵌入式的web服务,通过jar包运行就是一个web服务: 还有提供了很多metric,i ...

  2. 整合 springboot 和 swagger出问题

    整合 springboot 和 swagger ,出现报错, org.springframework.beans.factory.UnsatisfiedDependencyException: Err ...

  3. 【SpringBoot】搜索框架ElasticSearch介绍和整合SpringBoot

    ========================12章 搜索框架ElasticSearch介绍和整合SpringBoot ============================= 加入小D课堂技术交 ...

  4. netty-socketio整合springboot消息推送

    netty-socketio整合springboot消息推送 1.netty-socketio消息推送 1)在项目中常常涉及到消息推送的情况,消息推送要求的实时性,使用传统的方式已经不能满足需求了: ...

  5. 教你 Shiro 整合 SpringBoot,避开各种坑

    教你 Shiro 整合 SpringBoot,避开各种坑-----https://www.cnblogs.com/HowieYuan/p/9259638.html

  6. 基于 SpringBoot2.0+优雅整合 SpringBoot+Mybatis

    SpringBoot 整合 Mybatis 有两种常用的方式,一种就是我们常见的 xml 的方式 ,还有一种是全注解的方式.我觉得这两者没有谁比谁好,在 SQL 语句不太长的情况下,我觉得全注解的方式 ...

  7. 消息中间件——RabbitMQ(十)RabbitMQ整合SpringBoot实战!(全)

    前言 1. SpringBoot整合配置详解 publisher-confirms,实现一个监听器用于监听Broker端给我们返回的确认请求:RabbitTemplate.ConfirmCallbac ...

  8. Activiti7整合SpringBoot(十二)

    1 SpringBoot 整合 Activiti7 的配置 为了能够实现 SpringBoot 与 Activiti7 整合开发,首先我们要引入相关的依赖支持.所以,我们在工程的 pom.xml 文件 ...

  9. dubbo入门学习(三)-----dubbo整合springboot

    springboot节省了大量的精力去配置各种bean,因此通过一个简单的demo来整合springboot与dubbo 一.创建boot-user-service-provider 本篇博文基于上篇 ...

  10. liberty | 在IDEA整合Springboot与IBM liberty

    在IDEA整合Springboot与IBM liberty 简介 Liberty 是一款全新的轻量级应用服务器,它将用户的良好开发体验作为最主要的出发点.其主要特点和内容包括: 高模块化--该功能允许 ...

随机推荐

  1. 软件安装——tortoiseGit安装和配置

    Tortoisegit安装指南 TortoiseGit是一个开放的Git版本控制系统的源客户端,它是Git和Windows资源管理器的整合,提供了Git的图形化操作界面 一.软件安装 1.进入tort ...

  2. 本地文件上传 Gitee 和 GitHub

    新建仓库 上 GitHub 或者是 gitee 创建仓库 在所在的文件夹打开终端 在本地项目文件夹打开终端, 或者 cd 到本地项目文件夹 配置提交项目的用户名和提交项目的邮箱 git config ...

  3. 序列化框架-Kyro简述

    网上有很多资料说 Kryo 只能在 Java 上使用,这点是不对的,事实上除 Java 外,Scala 和 Kotlin 这些基于 JVM 的语言同样可以使用 Kryo 实现序列化. 1.使用方法 ( ...

  4. 图文并茂记录下重新配置Win10系统Flutter环境--内含Android Studio 下载安装教程

    Flutter 是什么 Flutter是Google开源的构建用户界面(UI)工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动.Web.桌面和嵌入式平台.Flutter 开源.免费,拥 ...

  5. 【Redis场景拓展】秒杀问题-全局唯一ID生成策略

    全局唯一ID 为什么要使用全局唯一ID: 当用户抢购时,就会生成订单并保存到订单表中,而订单表如果使用数据库自增ID就存在一些问题: 受单表数据量的限制 id的规律性太明显 场景分析一:如果我们的id ...

  6. 服务器搭建(CenOS 7 Apache + PHP _Mysql环境(LAMP))

    服务器搭建(CenOS 7 Apache + PHP _Mysql环境(LAMP)) 第一步.更换阿里云 yum源 curl -o /etc/yum.repos.d/CentOS-Base.repo  ...

  7. KingbaseES libstdc++.so.6/ version 'CXXABI_1.3.8'问题处理

    ERROR:libstdc++.so.6: version `CXXABI_1.3.8' not found (required by ...) 此文是以 CentOS Linux 7 (AltArc ...

  8. C# 学习async/await(个人理解)

    await : 等待的意思 async:异步(非同步) 当我们方法内部   存在await的时候,就返回出去 执行下一步 ,等await后面的方法执行完毕 在执行await下面的方法 一.我们先看正常 ...

  9. java应用定位高cpu占用几步操作

    1.top获取高cpu占用的pid,如266202.查看pid的线程情况, top -H -p 266203.把cpu高占用的线程号转为16进制,printf "%x" 26652 ...

  10. tomcat报错:java.io.IOException: No space left on device

    1 简介 今天网站很多页面访问突然就404了,路径分明没有变,是正确的,就很奇怪 排查日志发现报错java.io.IOException: No space left on device 这个错误,是 ...