|
|
@@ -1,465 +1,298 @@
|
|
|
-// package com.pavis.app.saasbacken.utils;
|
|
|
-//
|
|
|
-// import com.pavis.app.saasbacken.config.MinioConfig;
|
|
|
-// import io.minio.MinioClient;
|
|
|
-// import io.minio.ObjectStat;
|
|
|
-// import io.minio.PutObjectOptions;
|
|
|
-// import io.minio.Result;
|
|
|
-// import io.minio.errors.ErrorResponseException;
|
|
|
-// import io.minio.errors.InvalidExpiresRangeException;
|
|
|
-// import io.minio.messages.Bucket;
|
|
|
-// import io.minio.messages.DeleteError;
|
|
|
-// import io.minio.messages.Item;
|
|
|
-// import lombok.SneakyThrows;
|
|
|
-// import lombok.extern.slf4j.Slf4j;
|
|
|
-// import org.apache.commons.lang3.StringUtils;
|
|
|
-// import org.springframework.beans.factory.annotation.Autowired;
|
|
|
-// import org.springframework.stereotype.Component;
|
|
|
-// import org.springframework.web.multipart.MultipartFile;
|
|
|
-//
|
|
|
-// import javax.annotation.PostConstruct;
|
|
|
-// import javax.annotation.Resource;
|
|
|
-// import javax.servlet.ServletOutputStream;
|
|
|
-// import javax.servlet.http.HttpServletResponse;
|
|
|
-// import java.io.InputStream;
|
|
|
-// import java.nio.charset.StandardCharsets;
|
|
|
-// import java.util.ArrayList;
|
|
|
-// import java.util.List;
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * @program: push-saas
|
|
|
-// * @description:
|
|
|
-// * @author: Guanzi
|
|
|
-// * @created: 2021/11/02 13:33
|
|
|
-// */
|
|
|
-// @Slf4j
|
|
|
-// @Component
|
|
|
-// public class MinioUtils {
|
|
|
-//
|
|
|
-// @Autowired
|
|
|
-// private MinioClient minioClient;
|
|
|
-//
|
|
|
-//
|
|
|
-//
|
|
|
-// private static final int DEFAULT_EXPIRY_TIME = 7 * 24 * 3600;
|
|
|
-//
|
|
|
-// @Resource
|
|
|
-// private MinioConfig minioConfig ;
|
|
|
-//
|
|
|
-//
|
|
|
-// //
|
|
|
-// // /**
|
|
|
-// // * 初始化 MinIO 客户端
|
|
|
-// // */
|
|
|
-// // @PostConstruct
|
|
|
-// // private void init(){
|
|
|
-// // try {
|
|
|
-// // minioClient = new MinioClient(minioConfig.getEndpoint(),
|
|
|
-// // minioConfig.getAccessKey(),
|
|
|
-// // minioConfig.getSecretKey());
|
|
|
-// // } catch (Exception e) {
|
|
|
-// // e.printStackTrace();
|
|
|
-// // log.info("MinIoClient init fail ...");
|
|
|
-// // }
|
|
|
-// // }
|
|
|
-//
|
|
|
-// // /**
|
|
|
-// // * 上传 <html> 页面
|
|
|
-// // */
|
|
|
-// // public String uploadHtml (String fileName, String filePath) throws Exception {
|
|
|
-// // minioClient.putObject(minioConfig.getBucketName(),fileName,filePath);
|
|
|
-// // return minioConfig.getEndpoint()+"/"+minioConfig.getBucketName()+"/"+fileName ;
|
|
|
-// // }
|
|
|
-// //
|
|
|
-// // /**
|
|
|
-// // * 上传 <img> 图片
|
|
|
-// // */
|
|
|
-// // public String uploadImg (String imgName, String imgPath) throws Exception {
|
|
|
-// // minioClient.putObject(minioConfig.getBucketName(),imgName,imgPath);
|
|
|
-// // return minioConfig.getEndpoint()+"/"+minioConfig.getBucketName()+"/"+imgName ;
|
|
|
-// // }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 检查存储桶是否存在
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public boolean bucketExists(String bucketName) {
|
|
|
-// boolean flag = false;
|
|
|
-// flag = minioClient.bucketExists(bucketName);
|
|
|
-// if (flag) {
|
|
|
-// return true;
|
|
|
-// }
|
|
|
-// return false;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 创建存储桶
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public boolean makeBucket(String bucketName) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// if (!flag) {
|
|
|
-// minioClient.makeBucket(bucketName);
|
|
|
-// return true;
|
|
|
-// } else {
|
|
|
-// return false;
|
|
|
-// }
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 列出所有存储桶名称
|
|
|
-// *
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public List<String> listBucketNames() {
|
|
|
-// List<Bucket> bucketList = listBuckets();
|
|
|
-// List<String> bucketListName = new ArrayList<>();
|
|
|
-// for (Bucket bucket : bucketList) {
|
|
|
-// bucketListName.add(bucket.name());
|
|
|
-// }
|
|
|
-// return bucketListName;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 列出所有存储桶
|
|
|
-// *
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public List<Bucket> listBuckets() {
|
|
|
-// return minioClient.listBuckets();
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 删除存储桶
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public boolean removeBucket(String bucketName) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// if (flag) {
|
|
|
-// Iterable<Result<Item>> myObjects = listObjects(bucketName);
|
|
|
-// for (Result<Item> result : myObjects) {
|
|
|
-// Item item = result.get();
|
|
|
-// // 有对象文件,则删除失败
|
|
|
-// if (item.size() > 0) {
|
|
|
-// return false;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// // 删除存储桶,注意,只有存储桶为空时才能删除成功。
|
|
|
-// minioClient.removeBucket(bucketName);
|
|
|
-// flag = bucketExists(bucketName);
|
|
|
-// if (!flag) {
|
|
|
-// return true;
|
|
|
-// }
|
|
|
-//
|
|
|
-// }
|
|
|
-// return false;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 列出存储桶中的所有对象名称
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public List<String> listObjectNames(String bucketName) {
|
|
|
-// List<String> listObjectNames = new ArrayList<>();
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// if (flag) {
|
|
|
-// Iterable<Result<Item>> myObjects = listObjects(bucketName);
|
|
|
-// for (Result<Item> result : myObjects) {
|
|
|
-// Item item = result.get();
|
|
|
-// listObjectNames.add(item.objectName());
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return listObjectNames;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 列出存储桶中的所有对象
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public Iterable<Result<Item>> listObjects(String bucketName) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// if (flag) {
|
|
|
-// return minioClient.listObjects(bucketName);
|
|
|
-// }
|
|
|
-// return null;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 通过文件上传到对象
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @param objectName 存储桶里的对象名称
|
|
|
-// * @param fileName File name
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public boolean putObject(String bucketName, String objectName, String fileName) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// if (flag) {
|
|
|
-// minioClient.putObject(bucketName, objectName, fileName, null);
|
|
|
-// ObjectStat statObject = statObject(bucketName, objectName);
|
|
|
-// if (statObject != null && statObject.length() > 0) {
|
|
|
-// return true;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return false;
|
|
|
-//
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 文件上传
|
|
|
-// *
|
|
|
-// * @param bucketName
|
|
|
-// * @param multipartFile
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public void putObject(String bucketName, MultipartFile multipartFile, String filename) {
|
|
|
-// PutObjectOptions putObjectOptions = new PutObjectOptions(multipartFile.getSize(), PutObjectOptions.MIN_MULTIPART_SIZE);
|
|
|
-// putObjectOptions.setContentType(multipartFile.getContentType());
|
|
|
-// minioClient.putObject(bucketName, filename, multipartFile.getInputStream(), putObjectOptions);
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 通过InputStream上传对象
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @param objectName 存储桶里的对象名称
|
|
|
-// * @param stream 要上传的流
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public boolean putObject(String bucketName, String objectName, InputStream stream) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// if (flag) {
|
|
|
-// minioClient.putObject(bucketName, objectName, stream, new PutObjectOptions(stream.available(), -1));
|
|
|
-// ObjectStat statObject = statObject(bucketName, objectName);
|
|
|
-// if (statObject != null && statObject.length() > 0) {
|
|
|
-// return true;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return false;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 以流的形式获取一个文件对象
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @param objectName 存储桶里的对象名称
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public InputStream getObject(String bucketName, String objectName) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// if (flag) {
|
|
|
-// ObjectStat statObject = statObject(bucketName, objectName);
|
|
|
-// if (statObject != null && statObject.length() > 0) {
|
|
|
-// InputStream stream = minioClient.getObject(bucketName, objectName);
|
|
|
-// return stream;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return null;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 以流的形式获取一个文件对象(断点下载)
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @param objectName 存储桶里的对象名称
|
|
|
-// * @param offset 起始字节的位置
|
|
|
-// * @param length 要读取的长度 (可选,如果无值则代表读到文件结尾)
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public InputStream getObject(String bucketName, String objectName, long offset, Long length) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// if (flag) {
|
|
|
-// ObjectStat statObject = statObject(bucketName, objectName);
|
|
|
-// if (statObject != null && statObject.length() > 0) {
|
|
|
-// InputStream stream = minioClient.getObject(bucketName, objectName, offset, length);
|
|
|
-// return stream;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return null;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 下载并将文件保存到本地
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @param objectName 存储桶里的对象名称
|
|
|
-// * @param fileName File name
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public boolean getObject(String bucketName, String objectName, String fileName) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// if (flag) {
|
|
|
-// ObjectStat statObject = statObject(bucketName, objectName);
|
|
|
-// if (statObject != null && statObject.length() > 0) {
|
|
|
-// minioClient.getObject(bucketName, objectName, fileName);
|
|
|
-// return true;
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return false;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 删除一个对象
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @param objectName 存储桶里的对象名称
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public boolean removeObject(String bucketName, String objectName) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// if (flag) {
|
|
|
-// minioClient.removeObject(bucketName, objectName);
|
|
|
-// return true;
|
|
|
-// }
|
|
|
-// return false;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 删除指定桶的多个文件对象,返回删除错误的对象列表,全部删除成功,返回空列表
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @param objectNames 含有要删除的多个object名称的迭代器对象
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public List<String> removeObject(String bucketName, List<String> objectNames) {
|
|
|
-// List<String> deleteErrorNames = new ArrayList<>();
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// if (flag) {
|
|
|
-// Iterable<Result<DeleteError>> results = minioClient.removeObjects(bucketName, objectNames);
|
|
|
-// for (Result<DeleteError> result : results) {
|
|
|
-// DeleteError error = result.get();
|
|
|
-// deleteErrorNames.add(error.objectName());
|
|
|
-// }
|
|
|
-// }
|
|
|
-// return deleteErrorNames;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 生成一个给HTTP GET请求用的presigned URL。
|
|
|
-// * 浏览器/移动端的客户端可以用这个URL进行下载,即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间,默认值是7天。
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @param objectName 存储桶里的对象名称
|
|
|
-// * @param expires 失效时间(以秒为单位),默认是7天,不得大于七天
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public String presignedGetObject(String bucketName, String objectName, Integer expires) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// String url = "";
|
|
|
-// if (flag) {
|
|
|
-// if (expires < 1 || expires > DEFAULT_EXPIRY_TIME) {
|
|
|
-// throw new InvalidExpiresRangeException(expires,
|
|
|
-// "expires must be in range of 1 to " + DEFAULT_EXPIRY_TIME);
|
|
|
-// }
|
|
|
-// url = minioClient.presignedGetObject(bucketName, objectName, expires);
|
|
|
-// }
|
|
|
-// return url;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 生成一个给HTTP PUT请求用的presigned URL。
|
|
|
-// * 浏览器/移动端的客户端可以用这个URL进行上传,即使其所在的存储桶是私有的。这个presigned URL可以设置一个失效时间,默认值是7天。
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @param objectName 存储桶里的对象名称
|
|
|
-// * @param expires 失效时间(以秒为单位),默认是7天,不得大于七天
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public String presignedPutObject(String bucketName, String objectName, Integer expires) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// String url = "";
|
|
|
-// if (flag) {
|
|
|
-// if (expires < 1 || expires > DEFAULT_EXPIRY_TIME) {
|
|
|
-// throw new InvalidExpiresRangeException(expires,
|
|
|
-// "expires must be in range of 1 to " + DEFAULT_EXPIRY_TIME);
|
|
|
-// }
|
|
|
-// url = minioClient.presignedPutObject(bucketName, objectName, expires);
|
|
|
-// }
|
|
|
-// return url;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 获取对象的元数据
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @param objectName 存储桶里的对象名称
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public ObjectStat statObject(String bucketName, String objectName) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// if (flag) {
|
|
|
-// ObjectStat statObject = minioClient.statObject(bucketName, objectName);
|
|
|
-// return statObject;
|
|
|
-// }
|
|
|
-// return null;
|
|
|
-// }
|
|
|
-//
|
|
|
-// /**
|
|
|
-// * 文件访问路径
|
|
|
-// *
|
|
|
-// * @param bucketName 存储桶名称
|
|
|
-// * @param objectName 存储桶里的对象名称
|
|
|
-// * @return
|
|
|
-// */
|
|
|
-// @SneakyThrows
|
|
|
-// public String getObjectUrl(String bucketName, String objectName) {
|
|
|
-// boolean flag = bucketExists(bucketName);
|
|
|
-// String url = "";
|
|
|
-// if (flag) {
|
|
|
-// url = minioClient.getObjectUrl(bucketName, objectName);
|
|
|
-// }
|
|
|
-// return url;
|
|
|
-// }
|
|
|
-//
|
|
|
-//
|
|
|
-//
|
|
|
-// public void downloadFile(String bucketName, String fileName, String originalName, HttpServletResponse response) {
|
|
|
-// try {
|
|
|
-//
|
|
|
-// InputStream file = minioClient.getObject(bucketName, fileName);
|
|
|
-// String filename = new String(fileName.getBytes("ISO8859-1"), StandardCharsets.UTF_8);
|
|
|
-// if (StringUtils.isNotEmpty(originalName)) {
|
|
|
-// fileName = originalName;
|
|
|
-// }
|
|
|
-// 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();
|
|
|
-// } catch (ErrorResponseException e) {
|
|
|
-// e.printStackTrace();
|
|
|
-// } catch (Exception e) {
|
|
|
-// e.printStackTrace();
|
|
|
-// }
|
|
|
-// }
|
|
|
-// }
|
|
|
+package com.pavis.app.saasbacken.utils;
|
|
|
+
|
|
|
+import com.pavis.app.saasbacken.config.MinioConfig;
|
|
|
+import com.pavis.app.saasbacken.exception.OrgException;
|
|
|
+import com.pavis.app.saasbacken.http.ErrorCode;
|
|
|
+import io.minio.*;
|
|
|
+import io.minio.http.Method;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.springframework.stereotype.Component;
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
+
|
|
|
+import javax.annotation.Resource;
|
|
|
+import javax.servlet.http.HttpServletResponse;
|
|
|
+import java.io.IOException;
|
|
|
+import java.io.InputStream;
|
|
|
+import java.io.OutputStream;
|
|
|
+import java.net.HttpURLConnection;
|
|
|
+import java.net.URL;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.Date;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @program: push-saas
|
|
|
+ * @description:
|
|
|
+ * @author: Guanzi
|
|
|
+ * @created: 2021/11/02 13:33
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@Component
|
|
|
+public class MinioUtils {
|
|
|
+
|
|
|
+ private static final String NAME_HEAD = "J";
|
|
|
+ private static final String CONTENT_TYPE = "image/jpeg";
|
|
|
+ //MinIO服务的URL
|
|
|
+ private static String minIOUrl;
|
|
|
+ //Access key
|
|
|
+ private static String accessKey;
|
|
|
+ //Secret key
|
|
|
+ private static String secretKey;
|
|
|
+ //存储桶名称
|
|
|
+ private static String bucketName;
|
|
|
+ //文件大小(最大)
|
|
|
+ private static Integer maxFileSize = 10;
|
|
|
+ //签名有效时间 单位秒
|
|
|
+ private static Integer expires;
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 桶占位符
|
|
|
+ */
|
|
|
+ private static final String BUCKET_PARAM = "${bucket}";
|
|
|
+ /**
|
|
|
+ * bucket权限-读写
|
|
|
+ */
|
|
|
+ private static final String READ_WRITE = "{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetBucketLocation\",\"s3:ListBucket\",\"s3:ListBucketMultipartUploads\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "\"]},{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:DeleteObject\",\"s3:GetObject\",\"s3:ListMultipartUploadParts\",\"s3:PutObject\",\"s3:AbortMultipartUpload\"],\"Resource\":[\"arn:aws:s3:::" + BUCKET_PARAM + "/*\"]}]}";
|
|
|
+
|
|
|
+ @Resource
|
|
|
+ private MinioClient minioClient;
|
|
|
+
|
|
|
+ public MinioUtils() {
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public MinioUtils(String bucketName, MinioConfig minioConfig) {
|
|
|
+ this.minIOUrl = minioConfig.getEndpoint();
|
|
|
+ this.accessKey = minioConfig.getAccessKey();
|
|
|
+ this.secretKey = minioConfig.getSecretKey();
|
|
|
+ this.bucketName = bucketName;
|
|
|
+ this.maxFileSize = minioConfig.getMaxFileSize();
|
|
|
+ this.expires = minioConfig.getExpires();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 获取文件签名url
|
|
|
+ *
|
|
|
+ * @param fileName 文件名称
|
|
|
+ * @return 文件签名地址
|
|
|
+ */
|
|
|
+ public static String getSignedUrl(String fileName) throws Exception {
|
|
|
+ if (StringUtils.isBlank(fileName)) {
|
|
|
+ throw new OrgException(ErrorCode.FILENAME_NULL.getCode(),ErrorCode.FILENAME_NULL.getMessage());
|
|
|
+ }
|
|
|
+ MinioClient client = MinioClient.builder()
|
|
|
+ .endpoint(minIOUrl)
|
|
|
+ .credentials(accessKey, secretKey)
|
|
|
+ .build();
|
|
|
+ return client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
|
|
|
+ .method(Method.GET)
|
|
|
+ .bucket(bucketName)
|
|
|
+ .object(getFileName(fileName))
|
|
|
+ .expiry(expires).build());
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 根据图片路径
|
|
|
+ *
|
|
|
+ * @param response
|
|
|
+ * @param imgUrl 网络(服务器)图片路径
|
|
|
+ */
|
|
|
+ public static void getFileIO(HttpServletResponse response, String imgUrl) throws IOException {
|
|
|
+ OutputStream out = null;
|
|
|
+ InputStream inputStream = null;
|
|
|
+ try {
|
|
|
+ HttpURLConnection connection = (HttpURLConnection) new URL(imgUrl).openConnection();
|
|
|
+ connection.setReadTimeout(5000);
|
|
|
+ connection.setConnectTimeout(5000);
|
|
|
+ connection.setRequestMethod("GET");
|
|
|
+ if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
|
|
|
+ inputStream = connection.getInputStream();
|
|
|
+ response.setContentType("image/jpeg");
|
|
|
+ out = response.getOutputStream();
|
|
|
+ //读取文件流
|
|
|
+ int len = 0;
|
|
|
+ byte[] buffer = new byte[1024 * 10];
|
|
|
+ while ((len = inputStream.read(buffer)) != -1) {
|
|
|
+ out.write(buffer, 0, len);
|
|
|
+ }
|
|
|
+ out.flush();
|
|
|
+ }
|
|
|
+ } catch (IOException e) {
|
|
|
+ System.out.println("获取图片出现异常,图片路径为:" + imgUrl);
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ if (null != out) {
|
|
|
+ out.close();
|
|
|
+ }
|
|
|
+ if (null != inputStream) {
|
|
|
+ inputStream.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 返回文件URL
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String setFile(MultipartFile multipartFile) throws Exception {
|
|
|
+ return uploadFiles(setFileName(null, multipartFile), fileVerify(multipartFile));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 返回文件名称
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String upFile(MultipartFile multipartFile) throws Exception {
|
|
|
+ String fileName = setFileName(null, multipartFile);
|
|
|
+ uploadFiles(fileName, fileVerify(multipartFile));
|
|
|
+ return fileName;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 返回文件URL
|
|
|
+ *
|
|
|
+ * @param fileName 图片名称
|
|
|
+ * @param inputStream
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static String setFile(String fileName, InputStream inputStream) throws Exception {
|
|
|
+ if (StringUtils.isBlank(fileName)) {
|
|
|
+ throw new OrgException(ErrorCode.FILENAME_NULL.getCode(),ErrorCode.FILENAME_NULL.getMessage());
|
|
|
+ }
|
|
|
+ return uploadFiles(fileName, inputStream);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 返回文件URL
|
|
|
+ *
|
|
|
+ * @param fileName 图片名称
|
|
|
+ * @param multipartFile 文件
|
|
|
+ * @return 文件路径字符串(不可直接访问)
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public static String setFile(String fileName, MultipartFile multipartFile) throws Exception {
|
|
|
+ return uploadFiles(setFileName(fileName, multipartFile), fileVerify(multipartFile));
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 文件校验
|
|
|
+ */
|
|
|
+ private static InputStream fileVerify(MultipartFile multipartFile) throws IOException {
|
|
|
+ if (null == multipartFile) {
|
|
|
+ throw new OrgException(4035,"请选择文件");
|
|
|
+ }
|
|
|
+ // 文件不大于10M
|
|
|
+ if (!checkFileSize(multipartFile.getSize(), maxFileSize, "M")) {
|
|
|
+ // throw new CustomException("文件大小超限制");
|
|
|
+ throw new OrgException(4036,"文件大小超限制");
|
|
|
+ }
|
|
|
+ return multipartFile.getInputStream();
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 上传文件 (流的形式)
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private static String uploadFiles(String fileName, InputStream inputStream) throws Exception {
|
|
|
+ MinioClient client = MinioClient.builder().endpoint(minIOUrl).credentials(accessKey, secretKey).build();
|
|
|
+ makeBucket(client, bucketName);
|
|
|
+ //设置桶的读写权限
|
|
|
+ client.setBucketPolicy(SetBucketPolicyArgs.builder().bucket(bucketName).config(READ_WRITE.replace(BUCKET_PARAM, bucketName)).build());
|
|
|
+ client.putObject(PutObjectArgs.builder().bucket(bucketName).object(fileName).stream(inputStream, inputStream.available(), -1)
|
|
|
+ .contentType(CONTENT_TYPE).build());
|
|
|
+ return getObjectPrefixUrl(bucketName) + fileName;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 校验创建桶
|
|
|
+ *
|
|
|
+ * @param bucketName 桶
|
|
|
+ */
|
|
|
+ private static void makeBucket(MinioClient minioClient, String bucketName) throws Exception {
|
|
|
+ // 判断桶是否存在
|
|
|
+ boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
|
|
|
+ if (!isExist) {
|
|
|
+ log.info("存储桶{}不存在", bucketName);
|
|
|
+ // 新建桶
|
|
|
+ minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
|
|
+ log.info("新建存储桶{}", bucketName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 文件url前半段
|
|
|
+ *
|
|
|
+ * @param bucket 桶
|
|
|
+ * @return 前半段
|
|
|
+ */
|
|
|
+ public static String getObjectPrefixUrl(String bucket) {
|
|
|
+ return String.format("%s/%s/", minIOUrl, bucket);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private static String setFileName(String fileName, MultipartFile multipartFile) {
|
|
|
+ if (StringUtils.isNotBlank(fileName)) {
|
|
|
+ return fileName;
|
|
|
+ }
|
|
|
+ SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
|
|
|
+ String[] originalFilename = multipartFile.getOriginalFilename().split("\\.");
|
|
|
+ return NAME_HEAD + simpleDateFormat.format(new Date()) + getRandom() + "." + originalFilename[originalFilename.length - 1];
|
|
|
+ }
|
|
|
+
|
|
|
+ private static int getRandom() {
|
|
|
+ double ran = Math.random() * 9000 + 1000;
|
|
|
+ return (int) ran;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 判断文件大小
|
|
|
+ *
|
|
|
+ * @param len 文件长度
|
|
|
+ * @param size 限制大小
|
|
|
+ * @param unit 限制单位(B,K,M,G)
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static boolean checkFileSize(Long len, int size, String unit) {
|
|
|
+// long len = file.length();
|
|
|
+ double fileSize = 0;
|
|
|
+ if ("B".equals(unit.toUpperCase())) {
|
|
|
+ fileSize = (double) len;
|
|
|
+ } else if ("K".equals(unit.toUpperCase())) {
|
|
|
+ fileSize = (double) len / 1024;
|
|
|
+ } else if ("M".equals(unit.toUpperCase())) {
|
|
|
+ fileSize = (double) len / 1048576;
|
|
|
+ } else if ("G".equals(unit.toUpperCase())) {
|
|
|
+ fileSize = (double) len / 1073741824;
|
|
|
+ }
|
|
|
+ if (fileSize > size) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理文件名称(当fileName 不是文件名称为文件存储路径地址时)
|
|
|
+ *
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private static String getFileName(String fileName) {
|
|
|
+ if (fileName.contains("/")) {
|
|
|
+ String[] split = fileName.split("/");
|
|
|
+ return split[split.length - 1];
|
|
|
+ } else {
|
|
|
+ return fileName;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|