Minio整合SpringBoot
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的更多相关文章
- 整合springboot(app后台框架搭建四)
springboot可以说是为了适用SOA服务出现,一方面,极大的简便了配置,加速了开发速度:第二方面,也是一个嵌入式的web服务,通过jar包运行就是一个web服务: 还有提供了很多metric,i ...
- 整合 springboot 和 swagger出问题
整合 springboot 和 swagger ,出现报错, org.springframework.beans.factory.UnsatisfiedDependencyException: Err ...
- 【SpringBoot】搜索框架ElasticSearch介绍和整合SpringBoot
========================12章 搜索框架ElasticSearch介绍和整合SpringBoot ============================= 加入小D课堂技术交 ...
- netty-socketio整合springboot消息推送
netty-socketio整合springboot消息推送 1.netty-socketio消息推送 1)在项目中常常涉及到消息推送的情况,消息推送要求的实时性,使用传统的方式已经不能满足需求了: ...
- 教你 Shiro 整合 SpringBoot,避开各种坑
教你 Shiro 整合 SpringBoot,避开各种坑-----https://www.cnblogs.com/HowieYuan/p/9259638.html
- 基于 SpringBoot2.0+优雅整合 SpringBoot+Mybatis
SpringBoot 整合 Mybatis 有两种常用的方式,一种就是我们常见的 xml 的方式 ,还有一种是全注解的方式.我觉得这两者没有谁比谁好,在 SQL 语句不太长的情况下,我觉得全注解的方式 ...
- 消息中间件——RabbitMQ(十)RabbitMQ整合SpringBoot实战!(全)
前言 1. SpringBoot整合配置详解 publisher-confirms,实现一个监听器用于监听Broker端给我们返回的确认请求:RabbitTemplate.ConfirmCallbac ...
- Activiti7整合SpringBoot(十二)
1 SpringBoot 整合 Activiti7 的配置 为了能够实现 SpringBoot 与 Activiti7 整合开发,首先我们要引入相关的依赖支持.所以,我们在工程的 pom.xml 文件 ...
- dubbo入门学习(三)-----dubbo整合springboot
springboot节省了大量的精力去配置各种bean,因此通过一个简单的demo来整合springboot与dubbo 一.创建boot-user-service-provider 本篇博文基于上篇 ...
- liberty | 在IDEA整合Springboot与IBM liberty
在IDEA整合Springboot与IBM liberty 简介 Liberty 是一款全新的轻量级应用服务器,它将用户的良好开发体验作为最主要的出发点.其主要特点和内容包括: 高模块化--该功能允许 ...
随机推荐
- 软件安装——tortoiseGit安装和配置
Tortoisegit安装指南 TortoiseGit是一个开放的Git版本控制系统的源客户端,它是Git和Windows资源管理器的整合,提供了Git的图形化操作界面 一.软件安装 1.进入tort ...
- 本地文件上传 Gitee 和 GitHub
新建仓库 上 GitHub 或者是 gitee 创建仓库 在所在的文件夹打开终端 在本地项目文件夹打开终端, 或者 cd 到本地项目文件夹 配置提交项目的用户名和提交项目的邮箱 git config ...
- 序列化框架-Kyro简述
网上有很多资料说 Kryo 只能在 Java 上使用,这点是不对的,事实上除 Java 外,Scala 和 Kotlin 这些基于 JVM 的语言同样可以使用 Kryo 实现序列化. 1.使用方法 ( ...
- 图文并茂记录下重新配置Win10系统Flutter环境--内含Android Studio 下载安装教程
Flutter 是什么 Flutter是Google开源的构建用户界面(UI)工具包,帮助开发者通过一套代码库高效构建多平台精美应用,支持移动.Web.桌面和嵌入式平台.Flutter 开源.免费,拥 ...
- 【Redis场景拓展】秒杀问题-全局唯一ID生成策略
全局唯一ID 为什么要使用全局唯一ID: 当用户抢购时,就会生成订单并保存到订单表中,而订单表如果使用数据库自增ID就存在一些问题: 受单表数据量的限制 id的规律性太明显 场景分析一:如果我们的id ...
- 服务器搭建(CenOS 7 Apache + PHP _Mysql环境(LAMP))
服务器搭建(CenOS 7 Apache + PHP _Mysql环境(LAMP)) 第一步.更换阿里云 yum源 curl -o /etc/yum.repos.d/CentOS-Base.repo ...
- 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 ...
- C# 学习async/await(个人理解)
await : 等待的意思 async:异步(非同步) 当我们方法内部 存在await的时候,就返回出去 执行下一步 ,等await后面的方法执行完毕 在执行await下面的方法 一.我们先看正常 ...
- java应用定位高cpu占用几步操作
1.top获取高cpu占用的pid,如266202.查看pid的线程情况, top -H -p 266203.把cpu高占用的线程号转为16进制,printf "%x" 26652 ...
- tomcat报错:java.io.IOException: No space left on device
1 简介 今天网站很多页面访问突然就404了,路径分明没有变,是正确的,就很奇怪 排查日志发现报错java.io.IOException: No space left on device 这个错误,是 ...