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. [cocos2d-x]TextureCache和spriteFramecache

    SpriteFrameCache 主要服务于多张碎图合并出来的纹理图片.这种纹理在一张大图中包含了多张小图,直接通过TextureCache引用会有诸多不便,因而衍生出来精灵框帧的处理方式,即把截取好 ...

  2. 基于AbstractProcessor扩展MapStruct自动生成实体映射工具类

    作者:京东物流 王北永 姚再毅 1 背景 日常开发过程中,尤其在 DDD 过程中,经常遇到 VO/MODEL/PO 等领域模型的相互转换.此时我们会一个字段一个字段进行 set|get 设置.要么使用 ...

  3. Java JDK1.5: 泛型 新特性的讲解说明

    Java JDK1.5: 泛型 新特性的讲解说明 每博一文案 听到过这样一句话:"三观没有标准.在乌鸦的世界里,天鹅也有罪." 环境.阅历的不同,造就了每个人独有的世界观.人生观. ...

  4. DataX二次开发——新增HiveReader插件

    一.研发背景 DataX官方开源的版本支持HDFS文件的读写,并没有支持基于JDBC的Hive数据读写,很多时候一些数据同步不太方便,比如在读取Hive之前先执行一些sql.读取一些Hive的视图数据 ...

  5. windows环境下安装es和kibana

    1 ES安装 1.1 下载地址 https://www.elastic.co/cn/downloads/elasticsearch 1.2 版本选择 注意选择合适的版本,ES依赖于JDK,需要有对应的 ...

  6. Java 调用 PaddleDetection 模型

    文章地址 介绍 训练好的模型要给业务调用,deepjavalibrary/djl:Java 中与引擎无关的深度学习框架 (github.com) 可以完成这件事,它支持使用 Java 调用 PyTor ...

  7. 郁金香 对MFC 编辑框的查看 与更改

    非常简单,本来想写一个带窗口的DLL注入工具 但是进程句柄可以拿到,但是好像开辟不了空间 注入DLL进不去 不知道怎么回事 这个问题,日后解决

  8. SpringBoot集成Tomcat服务

    目录 一.Tomcat集成 1.依赖层级 2.自动化配置 二.Tomcat架构 三.Tomcat配置 1.基础配置 2.属性配置类 3.配置加载分析 四.周期管理方法 1.控制类 2.核心方法 五.参 ...

  9. C语言排序 冒泡 选择 快排

    冒泡排序 冒泡排序是一种简单的排序算法,其基本思想是重复地交换相邻两个元素,将较大的元素向右"冒泡",较小的元素向左"沉淀",从而将序列中的最大元素逐渐移到最后 ...

  10. .Net依赖注入、控制反转

    依赖项是指另一个对象所依赖的对象. 使用其他类所依赖的 WriteMessage 方法检查以下 MyDependency 类:   public class MyDependency { public ...