From 492d84ae282e6d65f28322e9d6504be15f58df09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A0=BC=E6=B8=A9?= Date: Mon, 11 Mar 2024 17:52:17 +0800 Subject: [PATCH 1/2] =?UTF-8?q?=E9=98=BF=E9=87=8C=E4=BA=91OSS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 ++ .../springbok/storage/AliyunStorage.java | 76 +++++++++++++++++++ .../springbok/storage/LocalStorage.java | 14 +--- .../src/main/resources/application-dev.yml | 6 ++ .../springbok/config/StorageAutoConfig.java | 15 ++++ .../properties/StorageProperties.java | 40 +++------- 6 files changed, 115 insertions(+), 43 deletions(-) create mode 100644 springbok-common/src/main/java/cn/code4java/springbok/storage/AliyunStorage.java diff --git a/pom.xml b/pom.xml index 0abf06a..a94f88d 100644 --- a/pom.xml +++ b/pom.xml @@ -41,6 +41,7 @@ 1.37.0 1.9.3 4.3.0 + 3.15.1 @@ -135,6 +136,12 @@ knife4j-openapi3-spring-boot-starter ${knife4j-openapi3.version} + + + com.aliyun.oss + aliyun-sdk-oss + ${aliyun.oss.version} + diff --git a/springbok-common/src/main/java/cn/code4java/springbok/storage/AliyunStorage.java b/springbok-common/src/main/java/cn/code4java/springbok/storage/AliyunStorage.java new file mode 100644 index 0000000..8c1816f --- /dev/null +++ b/springbok-common/src/main/java/cn/code4java/springbok/storage/AliyunStorage.java @@ -0,0 +1,76 @@ +package cn.code4java.springbok.storage; + +import cn.code4java.springbok.enums.OSSDistrictEnum; +import com.aliyun.oss.OSS; +import com.aliyun.oss.OSSClientBuilder; +import com.aliyun.oss.model.*; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.io.InputStream; + +/** + * @ClassName AliyunStorage + * @Description: 阿里云OSS + * @Author fengwensheng + * @Date 2024/03/11 + * @Version V1.0 + **/ +@Slf4j +@Data +public class AliyunStorage implements Storage { + + private String bucketName = "springbok"; + private String endpoint = "oss-cn-guangzhou.aliyuncs.com"; + private String accessKeyId; + private String accessKeySecret; + + @Override + public void store(InputStream inputStream, String contentType, String keyName, int type) { + OSSDistrictEnum ossDistrictEnum = OSSDistrictEnum.getOSSDistrictEnum(type); + // 创建bucket + createBucket(bucketName); + ObjectMetadata objectMetadata = new ObjectMetadata(); + objectMetadata.setContentType(contentType); + PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, ossDistrictEnum.getValue() + "/" + keyName, inputStream, objectMetadata); + getOSSClient().putObject(putObjectRequest); + } + + @Override + public String generateUrl(String keyName, int type) { + OSSDistrictEnum ossDistrictEnum = OSSDistrictEnum.getOSSDistrictEnum(type); + return "https://" + bucketName + "." + endpoint + "/" + ossDistrictEnum.getValue() + "/" + keyName; + } + + /** + * 创建bucket + */ + private void createBucket(String bucketName) { + OSS ossClient = getOSSClient(); + try { + // 创建存储空间 + boolean exists = ossClient.doesBucketExist(bucketName); + if (!exists) { + CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); + // 设置存储空间读写权限为公共读,默认为私有 + createBucketRequest.setCannedACL(CannedAccessControlList.PublicRead); + ossClient.createBucket(createBucketRequest); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (ossClient != null) { + ossClient.shutdown(); + } + } + } + + /** + * 创建OSS实例 + * + * @return + */ + private OSS getOSSClient() { + return new OSSClientBuilder().build("https://" + endpoint, accessKeyId, accessKeySecret); + } +} diff --git a/springbok-common/src/main/java/cn/code4java/springbok/storage/LocalStorage.java b/springbok-common/src/main/java/cn/code4java/springbok/storage/LocalStorage.java index f5efe52..60b4432 100644 --- a/springbok-common/src/main/java/cn/code4java/springbok/storage/LocalStorage.java +++ b/springbok-common/src/main/java/cn/code4java/springbok/storage/LocalStorage.java @@ -1,6 +1,7 @@ package cn.code4java.springbok.storage; import cn.code4java.springbok.enums.OSSDistrictEnum; +import lombok.Data; import lombok.extern.slf4j.Slf4j; import java.io.IOException; @@ -18,24 +19,13 @@ import java.nio.file.StandardCopyOption; * @Version V1.0 **/ @Slf4j +@Data public class LocalStorage implements Storage { private Path rootLocation; private String address; private String storagePath; - public void setStoragePath(String storagePath) { - this.storagePath = storagePath; - } - - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - @Override public void store(InputStream inputStream, String contentType, String keyName, int type) { try { diff --git a/springbok-core/src/main/resources/application-dev.yml b/springbok-core/src/main/resources/application-dev.yml index 7a85ffe..4176104 100644 --- a/springbok-core/src/main/resources/application-dev.yml +++ b/springbok-core/src/main/resources/application-dev.yml @@ -101,6 +101,12 @@ springbok: storagePath: storages # 返回前端的图片地址 address: http://localhost:9988/image/ + # 阿里云OSS配置 + aliyun: + # id + accessKeyId: xxx + # secret + accessKeySecret: xxx api: security: # 请求有效时间,单位:s diff --git a/springbok-system/src/main/java/cn/code4java/springbok/config/StorageAutoConfig.java b/springbok-system/src/main/java/cn/code4java/springbok/config/StorageAutoConfig.java index 455c28b..ac5aa3d 100644 --- a/springbok-system/src/main/java/cn/code4java/springbok/config/StorageAutoConfig.java +++ b/springbok-system/src/main/java/cn/code4java/springbok/config/StorageAutoConfig.java @@ -1,8 +1,10 @@ package cn.code4java.springbok.config; import cn.code4java.springbok.properties.StorageProperties; +import cn.code4java.springbok.storage.AliyunStorage; import cn.code4java.springbok.storage.LocalStorage; import cn.code4java.springbok.storage.StorageService; +import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -14,6 +16,7 @@ import org.springframework.context.annotation.Configuration; * @Date 2024/1/8 * @Version V1.0 **/ +@Slf4j @Configuration @EnableConfigurationProperties(StorageProperties.class) public class StorageAutoConfig { @@ -29,8 +32,11 @@ public class StorageAutoConfig { StorageService storageService = new StorageService(); String active = this.properties.getActive(); storageService.setActive(active); + log.info("当前存储模式为{}", active); if (active.equals("local")) { storageService.setStorage(localStorage()); + } else if (active.equals("aliyun")) { + storageService.setStorage(aliyunStorage()); } else { throw new RuntimeException("当前存储模式 " + active + " 不支持"); } @@ -46,4 +52,13 @@ public class StorageAutoConfig { localStorage.setStoragePath(local.getStoragePath()); return localStorage; } + + @Bean + public AliyunStorage aliyunStorage() { + AliyunStorage aliyunStorage = new AliyunStorage(); + StorageProperties.Aliyun aliyun = this.properties.getAliyun(); + aliyunStorage.setAccessKeyId(aliyun.getAccessKeyId()); + aliyunStorage.setAccessKeySecret(aliyun.getAccessKeySecret()); + return aliyunStorage; + } } diff --git a/springbok-system/src/main/java/cn/code4java/springbok/properties/StorageProperties.java b/springbok-system/src/main/java/cn/code4java/springbok/properties/StorageProperties.java index eacfd23..a75a39b 100644 --- a/springbok-system/src/main/java/cn/code4java/springbok/properties/StorageProperties.java +++ b/springbok-system/src/main/java/cn/code4java/springbok/properties/StorageProperties.java @@ -1,5 +1,6 @@ package cn.code4java.springbok.properties; +import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; /** @@ -9,45 +10,22 @@ import org.springframework.boot.context.properties.ConfigurationProperties; * @Date 2024/1/8 * @Version V1.0 **/ +@Data @ConfigurationProperties(prefix = "springbok.storage") public class StorageProperties { private String active; private Local local; + private Aliyun aliyun; - public String getActive() { - return active; - } - - public void setActive(String active) { - this.active = active; - } - - public Local getLocal() { - return local; - } - - public void setLocal(Local local) { - this.local = local; - } - + @Data public static class Local { private String address; private String storagePath; + } - public String getAddress() { - return address; - } - - public void setAddress(String address) { - this.address = address; - } - - public String getStoragePath() { - return storagePath; - } - - public void setStoragePath(String storagePath) { - this.storagePath = storagePath; - } + @Data + public static class Aliyun { + private String accessKeyId; + private String accessKeySecret; } } -- Gitee From 0852e4044f4d389da10e653e6e5e7e93520f5152 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A0=BC=E6=B8=A9?= Date: Tue, 12 Mar 2024 00:31:15 +0800 Subject: [PATCH 2/2] =?UTF-8?q?=E8=85=BE=E8=AE=AF=E4=BA=91COS?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pom.xml | 7 ++ .../springbok/storage/TencentStorage.java | 93 +++++++++++++++++++ .../src/main/resources/application-dev.yml | 8 ++ .../springbok/config/StorageAutoConfig.java | 14 +++ .../properties/StorageProperties.java | 8 ++ 5 files changed, 130 insertions(+) create mode 100644 springbok-common/src/main/java/cn/code4java/springbok/storage/TencentStorage.java diff --git a/pom.xml b/pom.xml index a94f88d..065550a 100644 --- a/pom.xml +++ b/pom.xml @@ -42,6 +42,7 @@ 1.9.3 4.3.0 3.15.1 + 5.6.155 @@ -142,6 +143,12 @@ aliyun-sdk-oss ${aliyun.oss.version} + + + com.qcloud + cos_api + ${tencent.cos.version} + diff --git a/springbok-common/src/main/java/cn/code4java/springbok/storage/TencentStorage.java b/springbok-common/src/main/java/cn/code4java/springbok/storage/TencentStorage.java new file mode 100644 index 0000000..b1c6e55 --- /dev/null +++ b/springbok-common/src/main/java/cn/code4java/springbok/storage/TencentStorage.java @@ -0,0 +1,93 @@ +package cn.code4java.springbok.storage; + +import cn.code4java.springbok.enums.OSSDistrictEnum; +import com.qcloud.cos.COSClient; +import com.qcloud.cos.ClientConfig; +import com.qcloud.cos.auth.BasicCOSCredentials; +import com.qcloud.cos.auth.BasicSessionCredentials; +import com.qcloud.cos.auth.COSCredentials; +import com.qcloud.cos.http.HttpProtocol; +import com.qcloud.cos.model.*; +import com.qcloud.cos.region.Region; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.io.InputStream; + +/** + * @ClassName TencentStorage + * @Description: 腾讯云COS + * @Author fengwensheng + * @Date 2024/03/12 + * @Version V1.0 + **/ +@Slf4j +@Data +public class TencentStorage implements Storage { + + private String bucketName = "springbok"; + private String endpoint = "ap-guangzhou"; + private String appId; + private String secretId; + private String secretKey; + + @Override + public void store(InputStream inputStream, String contentType, String keyName, int type) { + OSSDistrictEnum ossDistrictEnum = OSSDistrictEnum.getOSSDistrictEnum(type); + // 创建bucket + createBucket(bucketName); + ObjectMetadata objectMetadata = new ObjectMetadata(); + objectMetadata.setContentType(contentType); + PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, ossDistrictEnum.getValue() + "/" + keyName, inputStream, objectMetadata); + getCOSClient().putObject(putObjectRequest); + } + + @Override + public String generateUrl(String keyName, int type) { + OSSDistrictEnum ossDistrictEnum = OSSDistrictEnum.getOSSDistrictEnum(type); + return "https://" + bucketName + ".cos." + endpoint + ".myqcloud.com/" + ossDistrictEnum.getValue() + "/" + keyName; + } + + /** + * 创建bucket + */ + private void createBucket(String bucketName) { + COSClient cosClient = getCOSClient(); + try { + // 创建存储空间 + boolean exists = cosClient.doesBucketExist(bucketName); + if (!exists) { + CreateBucketRequest createBucketRequest = new CreateBucketRequest(bucketName); + // 设置 bucket 的权限为 Private(私有读写), 其他可选有公有读私有写, 公有读写 + createBucketRequest.setCannedAcl(CannedAccessControlList.PublicRead); + cosClient.createBucket(createBucketRequest); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (cosClient != null) { + cosClient.shutdown(); + } + } + } + + /** + * 创建COS实例 + * + * @return + */ + private COSClient getCOSClient() { + // 1 初始化用户身份信息(secretId, secretKey)。 + COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); + // 2 设置 bucket 的地域, COS 地域的简称请参见 https://cloud.tencent.com/document/product/436/6224 + // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。 + Region region = new Region(endpoint); + ClientConfig clientConfig = new ClientConfig(region); + // 这里建议设置使用 https 协议 + // 从 5.6.54 版本开始,默认使用了 https + clientConfig.setHttpProtocol(HttpProtocol.https); + // 3 生成 cos 客户端。 + COSClient cosClient = new COSClient(cred, clientConfig); + return cosClient; + } +} diff --git a/springbok-core/src/main/resources/application-dev.yml b/springbok-core/src/main/resources/application-dev.yml index 4176104..5ce4ce9 100644 --- a/springbok-core/src/main/resources/application-dev.yml +++ b/springbok-core/src/main/resources/application-dev.yml @@ -107,6 +107,14 @@ springbok: accessKeyId: xxx # secret accessKeySecret: xxx + # 腾讯云COS配置 + tencent: + # appId + appId: xxx + # secretId + secretId: xxx + # secretKey + secretKey: xxx api: security: # 请求有效时间,单位:s diff --git a/springbok-system/src/main/java/cn/code4java/springbok/config/StorageAutoConfig.java b/springbok-system/src/main/java/cn/code4java/springbok/config/StorageAutoConfig.java index ac5aa3d..3b73327 100644 --- a/springbok-system/src/main/java/cn/code4java/springbok/config/StorageAutoConfig.java +++ b/springbok-system/src/main/java/cn/code4java/springbok/config/StorageAutoConfig.java @@ -4,6 +4,7 @@ import cn.code4java.springbok.properties.StorageProperties; import cn.code4java.springbok.storage.AliyunStorage; import cn.code4java.springbok.storage.LocalStorage; import cn.code4java.springbok.storage.StorageService; +import cn.code4java.springbok.storage.TencentStorage; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; @@ -37,6 +38,8 @@ public class StorageAutoConfig { storageService.setStorage(localStorage()); } else if (active.equals("aliyun")) { storageService.setStorage(aliyunStorage()); + } else if (active.equals("tencent")) { + storageService.setStorage(tencentStorage()); } else { throw new RuntimeException("当前存储模式 " + active + " 不支持"); } @@ -61,4 +64,15 @@ public class StorageAutoConfig { aliyunStorage.setAccessKeySecret(aliyun.getAccessKeySecret()); return aliyunStorage; } + + @Bean + public TencentStorage tencentStorage() { + TencentStorage tencentStorage = new TencentStorage(); + StorageProperties.Tencent tencent = this.properties.getTencent(); + tencentStorage.setAppId(tencent.getAppId()); + tencentStorage.setSecretId(tencent.getSecretId()); + tencentStorage.setSecretKey(tencent.getSecretKey()); + tencentStorage.setBucketName(tencentStorage.getBucketName() + "-" + tencentStorage.getAppId()); + return tencentStorage; + } } diff --git a/springbok-system/src/main/java/cn/code4java/springbok/properties/StorageProperties.java b/springbok-system/src/main/java/cn/code4java/springbok/properties/StorageProperties.java index a75a39b..0a9ed2e 100644 --- a/springbok-system/src/main/java/cn/code4java/springbok/properties/StorageProperties.java +++ b/springbok-system/src/main/java/cn/code4java/springbok/properties/StorageProperties.java @@ -16,6 +16,7 @@ public class StorageProperties { private String active; private Local local; private Aliyun aliyun; + private Tencent tencent; @Data public static class Local { @@ -28,4 +29,11 @@ public class StorageProperties { private String accessKeyId; private String accessKeySecret; } + + @Data + public static class Tencent { + private String appId; + private String secretId; + private String secretKey; + } } -- Gitee