mirror of
https://github.com/zongzibinbin/MallChat.git
synced 2026-03-13 21:53:41 +08:00
fix:oss组件封装
This commit is contained in:
24
mallchat-tools/mallchat-oss-starter/pom.xml
Normal file
24
mallchat-tools/mallchat-oss-starter/pom.xml
Normal file
@@ -0,0 +1,24 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<parent>
|
||||
<artifactId>mallchat-tools</artifactId>
|
||||
<groupId>com.abin.mallchat</groupId>
|
||||
<version>1.0-SNAPSHOT</version>
|
||||
</parent>
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>mallchat-oss-starter</artifactId>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.abin.mallchat</groupId>
|
||||
<artifactId>mallchat-common-starter</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.abin.mallchat.oss;
|
||||
|
||||
import io.minio.MinioClient;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.boot.autoconfigure.condition.*;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@ConditionalOnClass({MinioClient.class})
|
||||
@EnableConfigurationProperties(OssProperties.class)
|
||||
@ConditionalOnExpression("${oss.enabled}")
|
||||
@ConditionalOnProperty(value = "oss.type", havingValue = "minio")
|
||||
public class MinIOConfiguration {
|
||||
|
||||
|
||||
@Bean
|
||||
@SneakyThrows
|
||||
@ConditionalOnMissingBean(MinioClient.class)
|
||||
public MinioClient minioClient(OssProperties ossProperties) {
|
||||
return MinioClient.builder()
|
||||
.endpoint(ossProperties.getEndpoint())
|
||||
.credentials(ossProperties.getAccessKey(), ossProperties.getSecretKey())
|
||||
.build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnBean({MinioClient.class})
|
||||
@ConditionalOnMissingBean(MinIOTemplate.class)
|
||||
public MinIOTemplate minioTemplate(MinioClient minioClient, OssProperties ossProperties) {
|
||||
return new MinIOTemplate(minioClient, ossProperties);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
package com.abin.mallchat.oss;
|
||||
|
||||
import cn.hutool.core.date.DatePattern;
|
||||
import cn.hutool.core.date.DateUtil;
|
||||
import cn.hutool.core.io.file.FileNameUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.abin.mallchat.oss.domain.OssReq;
|
||||
import com.abin.mallchat.oss.domain.OssResp;
|
||||
import io.minio.*;
|
||||
import io.minio.http.Method;
|
||||
import io.minio.messages.Bucket;
|
||||
import io.minio.messages.Item;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
@AllArgsConstructor
|
||||
public class MinIOTemplate {
|
||||
|
||||
/**
|
||||
* MinIO 客户端
|
||||
*/
|
||||
MinioClient minioClient;
|
||||
|
||||
/**
|
||||
* MinIO 配置类
|
||||
*/
|
||||
OssProperties ossProperties;
|
||||
|
||||
/**
|
||||
* 查询所有存储桶
|
||||
*
|
||||
* @return Bucket 集合
|
||||
*/
|
||||
@SneakyThrows
|
||||
public List<Bucket> listBuckets() {
|
||||
return minioClient.listBuckets();
|
||||
}
|
||||
|
||||
/**
|
||||
* 桶是否存在
|
||||
*
|
||||
* @param bucketName 桶名
|
||||
* @return 是否存在
|
||||
*/
|
||||
@SneakyThrows
|
||||
public boolean bucketExists(String bucketName) {
|
||||
return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建存储桶
|
||||
*
|
||||
* @param bucketName 桶名
|
||||
*/
|
||||
@SneakyThrows
|
||||
public void makeBucket(String bucketName) {
|
||||
if (!bucketExists(bucketName)) {
|
||||
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除一个空桶 如果存储桶存在对象不为空时,删除会报错。
|
||||
*
|
||||
* @param bucketName 桶名
|
||||
*/
|
||||
@SneakyThrows
|
||||
public void removeBucket(String bucketName) {
|
||||
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回临时带签名、过期时间一天、Get请求方式的访问URL
|
||||
*/
|
||||
@SneakyThrows
|
||||
public OssResp getPreSignedObjectUrl(OssReq req) {
|
||||
String absolutePath = req.isAutoPath() ? generateAutoPath(req) : req.getFilePath() + StrUtil.SLASH + req.getFileName();
|
||||
String url = minioClient.getPresignedObjectUrl(
|
||||
GetPresignedObjectUrlArgs.builder()
|
||||
.method(Method.PUT)
|
||||
.bucket(ossProperties.getBucketName())
|
||||
.object(absolutePath)
|
||||
.expiry(60 * 60 * 24)
|
||||
.build());
|
||||
return OssResp.builder()
|
||||
.uploadUrl(url)
|
||||
.downloadUrl(getDownloadUrl(ossProperties.getBucketName(), absolutePath))
|
||||
.build();
|
||||
}
|
||||
|
||||
private String getDownloadUrl(String bucket, String pathFile) {
|
||||
return ossProperties.getEndpoint() + StrUtil.SLASH + bucket + pathFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* GetObject接口用于获取某个文件(Object)。此操作需要对此Object具有读权限。
|
||||
*
|
||||
* @param bucketName 桶名
|
||||
* @param ossFilePath Oss文件路径
|
||||
*/
|
||||
@SneakyThrows
|
||||
public InputStream getObject(String bucketName, String ossFilePath) {
|
||||
return minioClient.getObject(
|
||||
GetObjectArgs.builder().bucket(bucketName).object(ossFilePath).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询桶的对象信息
|
||||
*
|
||||
* @param bucketName 桶名
|
||||
* @param recursive 是否递归查询
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Iterable<Result<Item>> listObjects(String bucketName, boolean recursive) {
|
||||
return minioClient.listObjects(
|
||||
ListObjectsArgs.builder().bucket(bucketName).recursive(recursive).build());
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成随机文件名,防止重复
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String generateAutoPath(OssReq req) {
|
||||
String uid = Optional.ofNullable(req.getUid()).map(String::valueOf).orElse("000000");
|
||||
cn.hutool.core.lang.UUID uuid = cn.hutool.core.lang.UUID.fastUUID();
|
||||
String suffix = FileNameUtil.getSuffix(req.getFileName());
|
||||
String yearAndMonth = DateUtil.format(new Date(), DatePattern.NORM_MONTH_PATTERN);
|
||||
return req.getFilePath() + StrUtil.SLASH + yearAndMonth + StrUtil.SLASH + uid + StrUtil.SLASH + uuid + StrUtil.DOT + suffix;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取带签名的临时上传元数据对象,前端可获取后,直接上传到Minio
|
||||
*
|
||||
* @param bucketName
|
||||
* @param fileName
|
||||
* @return
|
||||
*/
|
||||
@SneakyThrows
|
||||
public Map<String, String> getPreSignedPostFormData(String bucketName, String fileName) {
|
||||
// 为存储桶创建一个上传策略,过期时间为7天
|
||||
PostPolicy policy = new PostPolicy(bucketName, ZonedDateTime.now().plusDays(7));
|
||||
// 设置一个参数key,值为上传对象的名称
|
||||
policy.addEqualsCondition("key", fileName);
|
||||
// 添加Content-Type以"image/"开头,表示只能上传照片
|
||||
policy.addStartsWithCondition("Content-Type", "image/");
|
||||
// 设置上传文件的大小 64kiB to 10MiB.
|
||||
policy.addContentLengthRangeCondition(64 * 1024, 10 * 1024 * 1024);
|
||||
return minioClient.getPresignedPostFormData(policy);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.abin.mallchat.oss;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class OssFile {
|
||||
/**
|
||||
* OSS 存储时文件路径
|
||||
*/
|
||||
String ossFilePath;
|
||||
/**
|
||||
* 原始文件名
|
||||
*/
|
||||
String originalFileName;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.abin.mallchat.oss;
|
||||
|
||||
import lombok.Data;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
@Data
|
||||
@ConfigurationProperties(prefix = "oss")
|
||||
public class OssProperties {
|
||||
|
||||
/**
|
||||
* 是否开启
|
||||
*/
|
||||
Boolean enabled;
|
||||
|
||||
/**
|
||||
* 存储对象服务器类型
|
||||
*/
|
||||
OssType type;
|
||||
|
||||
/**
|
||||
* OSS 访问端点,集群时需提供统一入口
|
||||
*/
|
||||
String endpoint;
|
||||
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
String accessKey;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
String secretKey;
|
||||
|
||||
/**
|
||||
* 存储桶
|
||||
*/
|
||||
String bucketName;
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.abin.mallchat.oss;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@AllArgsConstructor
|
||||
public enum OssType {
|
||||
/**
|
||||
* Minio 对象存储
|
||||
*/
|
||||
MINIO("minio", 1),
|
||||
|
||||
/**
|
||||
* 华为 OBS
|
||||
*/
|
||||
OBS("obs", 2),
|
||||
|
||||
/**
|
||||
* 腾讯 COS
|
||||
*/
|
||||
COS("tencent", 3),
|
||||
|
||||
/**
|
||||
* 阿里巴巴 SSO
|
||||
*/
|
||||
ALIBABA("alibaba", 4),
|
||||
;
|
||||
|
||||
/**
|
||||
* 名称
|
||||
*/
|
||||
final String name;
|
||||
/**
|
||||
* 类型
|
||||
*/
|
||||
final int type;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.abin.mallchat.oss.domain;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
|
||||
/**
|
||||
* Description: 上传url请求入参
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-23
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class OssReq {
|
||||
@ApiModelProperty(value = "文件存储路径")
|
||||
private String filePath;
|
||||
@ApiModelProperty(value = "文件名")
|
||||
private String fileName;
|
||||
@ApiModelProperty(value = "请求的uid")
|
||||
private Long uid;
|
||||
@ApiModelProperty(value = "自动生成地址")
|
||||
@Builder.Default
|
||||
private boolean autoPath = true;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.abin.mallchat.oss.domain;
|
||||
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
|
||||
/**
|
||||
* Description: 上传url请求出参
|
||||
* Author: <a href="https://github.com/zongzibinbin">abin</a>
|
||||
* Date: 2023-03-23
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
public class OssResp {
|
||||
|
||||
@ApiModelProperty(value = "上传的临时url")
|
||||
private String uploadUrl;
|
||||
|
||||
@ApiModelProperty(value = "成功后能够下载的url")
|
||||
private String downloadUrl;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
# Auto Configure
|
||||
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
|
||||
com.abin.mallchat.oss.MinIOConfiguration
|
||||
Reference in New Issue
Block a user