|
@@ -0,0 +1,209 @@
|
|
|
|
+package top.lifuquan.dao;
|
|
|
|
+
|
|
|
|
+import java.text.DateFormat;
|
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.util.UUID;
|
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
|
+
|
|
|
|
+import org.springframework.stereotype.Repository;
|
|
|
|
+import org.springframework.web.multipart.MultipartFile;
|
|
|
|
+
|
|
|
|
+import io.minio.BucketExistsArgs;
|
|
|
|
+import io.minio.GetPresignedObjectUrlArgs;
|
|
|
|
+import io.minio.ListObjectsArgs;
|
|
|
|
+import io.minio.MakeBucketArgs;
|
|
|
|
+import io.minio.MinioClient;
|
|
|
|
+import io.minio.PutObjectArgs;
|
|
|
|
+import io.minio.Result;
|
|
|
|
+import io.minio.http.Method;
|
|
|
|
+import io.minio.messages.Bucket;
|
|
|
|
+import io.minio.messages.Item;
|
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
+import top.lifuquan.exception.minio.MinioClientGetFailed;
|
|
|
|
+import top.lifuquan.exception.minio.MinioClientPutFailed;
|
|
|
|
+
|
|
|
|
+@Slf4j
|
|
|
|
+@Repository
|
|
|
|
+public class MinioDao {
|
|
|
|
+
|
|
|
|
+ private final MinioClient minioClient;
|
|
|
|
+
|
|
|
|
+ public MinioDao(MinioClient minioClient) {
|
|
|
|
+ this.minioClient = minioClient;
|
|
|
|
+ log.info("已完成{}装配", this.getClass().getName());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * 获取文件名列表
|
|
|
|
+ */
|
|
|
|
+ public List<String> listFileNames(String bucketName) throws MinioClientGetFailed {
|
|
|
|
+ return listFileNames(bucketName, null);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * 获取文件名列表
|
|
|
|
+ */
|
|
|
|
+ public List<String> listFileNames(String bucketName, String prefix) throws MinioClientGetFailed {
|
|
|
|
+ Iterable<Result<Item>> results = minioClient
|
|
|
|
+ .listObjects(ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).build());
|
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
|
+ try {
|
|
|
|
+ for (Result<Item> item : results) {
|
|
|
|
+ result.add(item.get().objectName());
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ // result.get() 异常
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ throw new MinioClientGetFailed("通过bucket名称 {} 获取内部元素列表失败", bucketName);
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * 通过bucket名称打印元素列表
|
|
|
|
+ */
|
|
|
|
+ public void printItemsByBucketName(String bucketName) throws MinioClientGetFailed {
|
|
|
|
+ Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder().bucket(bucketName).build());
|
|
|
|
+ Item item;
|
|
|
|
+ try {
|
|
|
|
+ for (Result<Item> result : results) {
|
|
|
|
+ item = result.get();
|
|
|
|
+ // 路径有很多属性是null
|
|
|
|
+ if (item.isDir()) {
|
|
|
|
+ log.info("路径--属性打印-------- objectName: {}-- size:{}-- owner:{}-- isLatest:{}-- isDir:{}",
|
|
|
|
+ item.objectName(), item.size(), item.owner(), item.isLatest(), item.isDir());
|
|
|
|
+ } else {
|
|
|
|
+ log.info("元素--属性打印-------- objectName: {}-- lastModified:{}-- etag:{}-- size:{}--"
|
|
|
|
+ + " storageClass:{}-- owner:{}-- userMetadata:{}-- isLatest:{}--"
|
|
|
|
+ + " versionId:{}-- isDir:{}-- isDeleteMarker:{}",
|
|
|
|
+ item.objectName(),
|
|
|
|
+ item.lastModified(),
|
|
|
|
+ item.etag(),
|
|
|
|
+ item.size(),
|
|
|
|
+ item.storageClass(),
|
|
|
|
+ item.owner().displayName(),
|
|
|
|
+ item.userMetadata(),
|
|
|
|
+ item.isLatest(),
|
|
|
|
+ item.versionId(),
|
|
|
|
+ item.isDir(),
|
|
|
|
+ item.isDeleteMarker());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ // result.get() 异常
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ throw new MinioClientGetFailed("通过bucket名称 {} 获取内部元素列表失败", bucketName);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * 获取全部的bucket名称
|
|
|
|
+ */
|
|
|
|
+ public List<String> listBucketNames() throws MinioClientGetFailed {
|
|
|
|
+ try {
|
|
|
|
+ List<Bucket> buckets = minioClient.listBuckets();
|
|
|
|
+ List<String> result = new ArrayList<>();
|
|
|
|
+ for (Bucket bucket : buckets) {
|
|
|
|
+ result.add(bucket.name());
|
|
|
|
+ }
|
|
|
|
+ return result;
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ throw new MinioClientGetFailed("获取bucket列表失败");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * 上传文件
|
|
|
|
+ * 自动添加日期,格式20221109/
|
|
|
|
+ * prefix为null 最终格式 20221109/fileName
|
|
|
|
+ * prefix为abc 最终格式为 abc/20221109/fileName
|
|
|
|
+ * minio上传完全相同路径文件会覆盖,在文件名之前加上一个uuid字符串
|
|
|
|
+ * 返回文件在bucket中的完整路径
|
|
|
|
+ */
|
|
|
|
+ public String upload(MultipartFile file, String bucketName, String prefix) {
|
|
|
|
+ // 在原始文件基础上添加日期和前缀
|
|
|
|
+ String filePath;
|
|
|
|
+ DateFormat format = new SimpleDateFormat("yyyyMMdd/");
|
|
|
|
+ String uuid = UUID.randomUUID().toString().replace("-", "");
|
|
|
|
+ if (prefix != null) {
|
|
|
|
+ prefix = prefix.endsWith("/") ? prefix : prefix + "/";
|
|
|
|
+ filePath = prefix + format.format(System.currentTimeMillis()) + uuid + "-" + file.getOriginalFilename();
|
|
|
|
+ } else {
|
|
|
|
+ filePath = format.format(System.currentTimeMillis()) + uuid + "-" + file.getOriginalFilename();
|
|
|
|
+ }
|
|
|
|
+ PutObjectArgs args;
|
|
|
|
+ try {
|
|
|
|
+ args = PutObjectArgs
|
|
|
|
+ .builder()
|
|
|
|
+ .bucket(bucketName)
|
|
|
|
+ .object(filePath)
|
|
|
|
+ .stream(file.getInputStream(), file.getSize(), -1)
|
|
|
|
+ .contentType(file.getContentType())
|
|
|
|
+ .build();
|
|
|
|
+ minioClient.putObject(args);
|
|
|
|
+ return filePath;
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ // file.getInputStream() 异常 IOException
|
|
|
|
+ // minioClient.putObject(args) 异常 一大堆
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * 获取download链接,默认7天有效
|
|
|
|
+ */
|
|
|
|
+ public String download(String bucketName, String filePath) {
|
|
|
|
+ GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs
|
|
|
|
+ .builder()
|
|
|
|
+ .method(Method.GET)
|
|
|
|
+ .bucket(bucketName)
|
|
|
|
+ .object(filePath)
|
|
|
|
+ .expiry(7, TimeUnit.DAYS)
|
|
|
|
+ .build();
|
|
|
|
+ try {
|
|
|
|
+ return minioClient.getPresignedObjectUrl(args);
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ return null;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * 检查bucket是否存在
|
|
|
|
+ */
|
|
|
|
+ public boolean bucketExists(String bucketName) throws Exception {
|
|
|
|
+ try {
|
|
|
|
+ return minioClient.bucketExists(BucketExistsArgs
|
|
|
|
+ .builder()
|
|
|
|
+ .bucket(bucketName)
|
|
|
|
+ .build());
|
|
|
|
+ } catch (IllegalArgumentException e) {
|
|
|
|
+ throw new MinioClientGetFailed("输入的bucketName--{}--不符合Amazon S3规范: {}", bucketName, e.getMessage());
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ throw new MinioClientGetFailed("查询BucketExists出错--{}--{}", bucketName, e.getMessage());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /*
|
|
|
|
+ * 创建bucket
|
|
|
|
+ */
|
|
|
|
+ public void makeBucket(String bucketName) throws Exception {
|
|
|
|
+ try {
|
|
|
|
+ minioClient.makeBucket(MakeBucketArgs
|
|
|
|
+ .builder()
|
|
|
|
+ .bucket(bucketName)
|
|
|
|
+ .build());
|
|
|
|
+ } catch (IllegalArgumentException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ throw new MinioClientPutFailed("输入的bucketName--{}--不符合Amazon S3规范: {}", bucketName, e.getMessage());
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ throw new MinioClientPutFailed("Bucket--{}--创建失败", bucketName);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|