mirror of
https://github.com/chillzhuang/blade-tool
synced 2025-03-14 09:37:25 +08:00
🎉 增加腾讯云oss实现
This commit is contained in:
parent
47eb3b411a
commit
82bdc04b57
@ -41,6 +41,12 @@
|
|||||||
<artifactId>qiniu-java-sdk</artifactId>
|
<artifactId>qiniu-java-sdk</artifactId>
|
||||||
<version>7.9.4</version>
|
<version>7.9.4</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!--腾讯COS-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.qcloud</groupId>
|
||||||
|
<artifactId>cos_api</artifactId>
|
||||||
|
<version>5.6.147</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
@ -0,0 +1,280 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2018-2099, yangkai.shen.
|
||||||
|
* <p>
|
||||||
|
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springblade.core.oss;
|
||||||
|
|
||||||
|
import com.qcloud.cos.COSClient;
|
||||||
|
import com.qcloud.cos.model.CannedAccessControlList;
|
||||||
|
import com.qcloud.cos.model.ObjectMetadata;
|
||||||
|
import com.qcloud.cos.model.PutObjectResult;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.SneakyThrows;
|
||||||
|
import org.springblade.core.oss.model.BladeFile;
|
||||||
|
import org.springblade.core.oss.model.OssFile;
|
||||||
|
import org.springblade.core.oss.props.OssProperties;
|
||||||
|
import org.springblade.core.oss.rule.OssRule;
|
||||||
|
import org.springblade.core.tool.utils.StringPool;
|
||||||
|
import org.springblade.core.tool.utils.StringUtil;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 腾讯云 COS 操作
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author yangkai.shen
|
||||||
|
* @date Created in 2020/1/7 17:24
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
public class TencentCosTemplate implements OssTemplate {
|
||||||
|
private final COSClient cosClient;
|
||||||
|
private final OssProperties ossProperties;
|
||||||
|
private final OssRule ossRule;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public void makeBucket(String bucketName) {
|
||||||
|
if (!bucketExists(bucketName)) {
|
||||||
|
cosClient.createBucket(getBucketName(bucketName));
|
||||||
|
// TODO: 权限是否需要修改为私有,当前为 公有读、私有写
|
||||||
|
cosClient.setBucketAcl(getBucketName(bucketName), CannedAccessControlList.PublicRead);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public void removeBucket(String bucketName) {
|
||||||
|
cosClient.deleteBucket(getBucketName(bucketName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public boolean bucketExists(String bucketName) {
|
||||||
|
return cosClient.doesBucketExist(getBucketName(bucketName));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public void copyFile(String bucketName, String fileName, String destBucketName) {
|
||||||
|
cosClient.copyObject(getBucketName(bucketName), fileName, getBucketName(destBucketName), fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public void copyFile(String bucketName, String fileName, String destBucketName, String destFileName) {
|
||||||
|
cosClient.copyObject(getBucketName(bucketName), fileName, getBucketName(destBucketName), destFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public OssFile statFile(String fileName) {
|
||||||
|
return statFile(ossProperties.getBucketName(), fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public OssFile statFile(String bucketName, String fileName) {
|
||||||
|
ObjectMetadata stat = cosClient.getObjectMetadata(getBucketName(bucketName), fileName);
|
||||||
|
OssFile ossFile = new OssFile();
|
||||||
|
ossFile.setName(fileName);
|
||||||
|
ossFile.setLink(fileLink(ossFile.getName()));
|
||||||
|
ossFile.setHash(stat.getContentMD5());
|
||||||
|
ossFile.setLength(stat.getContentLength());
|
||||||
|
ossFile.setPutTime(stat.getLastModified());
|
||||||
|
ossFile.setContentType(stat.getContentType());
|
||||||
|
return ossFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public String filePath(String fileName) {
|
||||||
|
return getOssHost().concat(StringPool.SLASH).concat(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public String filePath(String bucketName, String fileName) {
|
||||||
|
return getOssHost(bucketName).concat(StringPool.SLASH).concat(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public String fileLink(String fileName) {
|
||||||
|
return getOssHost().concat(StringPool.SLASH).concat(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public String fileLink(String bucketName, String fileName) {
|
||||||
|
return getOssHost(bucketName).concat(StringPool.SLASH).concat(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件对象
|
||||||
|
*
|
||||||
|
* @param file 上传文件类
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public BladeFile putFile(MultipartFile file) {
|
||||||
|
return putFile(ossProperties.getBucketName(), file.getOriginalFilename(), file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param fileName 上传文件名
|
||||||
|
* @param file 上传文件类
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public BladeFile putFile(String fileName, MultipartFile file) {
|
||||||
|
return putFile(ossProperties.getBucketName(), fileName, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public BladeFile putFile(String bucketName, String fileName, MultipartFile file) {
|
||||||
|
return putFile(bucketName, fileName, file.getInputStream());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public BladeFile putFile(String fileName, InputStream stream) {
|
||||||
|
return putFile(ossProperties.getBucketName(), fileName, stream);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public BladeFile putFile(String bucketName, String fileName, InputStream stream) {
|
||||||
|
return put(bucketName, stream, fileName, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SneakyThrows
|
||||||
|
public BladeFile put(String bucketName, InputStream stream, String key, boolean cover) {
|
||||||
|
makeBucket(bucketName);
|
||||||
|
String originalName = key;
|
||||||
|
key = getFileName(key);
|
||||||
|
ObjectMetadata objectMetadata = new ObjectMetadata();
|
||||||
|
// 覆盖上传
|
||||||
|
if (cover) {
|
||||||
|
cosClient.putObject(getBucketName(bucketName), key, stream, objectMetadata);
|
||||||
|
} else {
|
||||||
|
PutObjectResult response = cosClient.putObject(getBucketName(bucketName), key, stream, objectMetadata);
|
||||||
|
int retry = 0;
|
||||||
|
int retryCount = 5;
|
||||||
|
while (!StringUtils.hasText(response.getETag()) && retry < retryCount) {
|
||||||
|
response = cosClient.putObject(getBucketName(bucketName), key, stream, objectMetadata);
|
||||||
|
retry++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BladeFile file = new BladeFile();
|
||||||
|
file.setOriginalName(originalName);
|
||||||
|
file.setName(key);
|
||||||
|
file.setDomain(getOssHost(bucketName));
|
||||||
|
file.setLink(fileLink(bucketName, key));
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public void removeFile(String fileName) {
|
||||||
|
cosClient.deleteObject(getBucketName(), fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public void removeFile(String bucketName, String fileName) {
|
||||||
|
cosClient.deleteObject(getBucketName(bucketName), fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public void removeFiles(List<String> fileNames) {
|
||||||
|
fileNames.forEach(this::removeFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SneakyThrows
|
||||||
|
public void removeFiles(String bucketName, List<String> fileNames) {
|
||||||
|
fileNames.forEach(fileName -> removeFile(getBucketName(bucketName), fileName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据规则生成存储桶名称规则
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
private String getBucketName() {
|
||||||
|
return getBucketName(ossProperties.getBucketName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据规则生成存储桶名称规则
|
||||||
|
*
|
||||||
|
* @param bucketName 存储桶名称
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
private String getBucketName(String bucketName) {
|
||||||
|
return ossRule.bucketName(bucketName).concat(StringPool.DASH).concat(ossProperties.getAppId());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据规则生成文件名称规则
|
||||||
|
*
|
||||||
|
* @param originalFilename 原始文件名
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private String getFileName(String originalFilename) {
|
||||||
|
return ossRule.fileName(originalFilename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取域名
|
||||||
|
*
|
||||||
|
* @param bucketName 存储桶名称
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getOssHost(String bucketName) {
|
||||||
|
String prefix = getEndpoint().contains("https://") ? "https://" : "http://";
|
||||||
|
return prefix + cosClient.getClientConfig().getEndpointBuilder().buildGeneralApiEndpoint(getBucketName(bucketName));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取域名
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getOssHost() {
|
||||||
|
return getOssHost(ossProperties.getBucketName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取服务地址
|
||||||
|
*
|
||||||
|
* @return String
|
||||||
|
*/
|
||||||
|
public String getEndpoint() {
|
||||||
|
if (StringUtil.isBlank(ossProperties.getTransformEndpoint())) {
|
||||||
|
return ossProperties.getEndpoint();
|
||||||
|
}
|
||||||
|
return StringUtil.removeSuffix(ossProperties.getTransformEndpoint(), StringPool.SLASH);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,81 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2018-2099, yangkai.shen.
|
||||||
|
* <p>
|
||||||
|
* Licensed under the GNU LESSER GENERAL PUBLIC LICENSE 3.0;
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
* <p>
|
||||||
|
* http://www.gnu.org/licenses/lgpl.html
|
||||||
|
* <p>
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.springblade.core.oss.config;
|
||||||
|
|
||||||
|
import com.qcloud.cos.COSClient;
|
||||||
|
import com.qcloud.cos.ClientConfig;
|
||||||
|
import com.qcloud.cos.auth.BasicCOSCredentials;
|
||||||
|
import com.qcloud.cos.auth.COSCredentials;
|
||||||
|
import com.qcloud.cos.region.Region;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springblade.core.oss.TencentCosTemplate;
|
||||||
|
import org.springblade.core.oss.props.OssProperties;
|
||||||
|
import org.springblade.core.oss.rule.OssRule;
|
||||||
|
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||||
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 腾讯云 COS 自动装配
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author yangkai.shen
|
||||||
|
* @date Created in 2020/1/7 17:24
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@AutoConfiguration(after = OssConfiguration.class)
|
||||||
|
@ConditionalOnClass({COSClient.class})
|
||||||
|
@EnableConfigurationProperties(OssProperties.class)
|
||||||
|
@ConditionalOnProperty(value = "oss.name", havingValue = "tencentcos")
|
||||||
|
public class TencentCosConfiguration {
|
||||||
|
|
||||||
|
private final OssProperties ossProperties;
|
||||||
|
private final OssRule ossRule;
|
||||||
|
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnMissingBean(COSClient.class)
|
||||||
|
public COSClient ossClient() {
|
||||||
|
// 初始化用户身份信息(secretId, secretKey)
|
||||||
|
COSCredentials credentials = new BasicCOSCredentials(ossProperties.getAccessKey(), ossProperties.getSecretKey());
|
||||||
|
// 设置 bucket 的区域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
|
||||||
|
Region region = new Region(ossProperties.getRegion());
|
||||||
|
// clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
|
||||||
|
ClientConfig clientConfig = new ClientConfig(region);
|
||||||
|
// 设置OSSClient允许打开的最大HTTP连接数,默认为1024个。
|
||||||
|
clientConfig.setMaxConnectionsCount(1024);
|
||||||
|
// 设置Socket层传输数据的超时时间,默认为50000毫秒。
|
||||||
|
clientConfig.setSocketTimeout(50000);
|
||||||
|
// 设置建立连接的超时时间,默认为50000毫秒。
|
||||||
|
clientConfig.setConnectionTimeout(50000);
|
||||||
|
// 设置从连接池中获取连接的超时时间(单位:毫秒),默认不超时。
|
||||||
|
clientConfig.setConnectionRequestTimeout(1000);
|
||||||
|
return new COSClient(credentials, clientConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@ConditionalOnBean({COSClient.class})
|
||||||
|
@ConditionalOnMissingBean(TencentCosTemplate.class)
|
||||||
|
public TencentCosTemplate tencentCosTemplate(COSClient cosClient) {
|
||||||
|
return new TencentCosTemplate(cosClient, ossProperties, ossRule);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -68,6 +68,16 @@ public class OssProperties {
|
|||||||
*/
|
*/
|
||||||
private String bucketName = "blade";
|
private String bucketName = "blade";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 应用ID TencentCOS需要
|
||||||
|
*/
|
||||||
|
private String appId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 区域简称 TencentCOS/Amazon S3 需要
|
||||||
|
*/
|
||||||
|
private String region;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 自定义属性
|
* 自定义属性
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user