一、MINIO的安装,MinioTemplate的封装使用
二、阿里云OSS,AliossTemplate的封装使用
三、七牛云对象存储,QiniuTemplate的封装使用
四、华为云OBS对象存储,HwObsTemplate的封装使用
五、腾讯COS对象存储,TxCosTemplate的封装使用
五、腾讯COS对象存储,TxCosTemplate的封装使用
在上一章《四、华为云OBS对象存储,HwObsTemplate的封装使用》对腾讯COS对象存储进行可简单的介绍封装。本节对腾讯COS对象存储同样基于MINIIO的思路,对桶的创建删除,文档的创建、删除、文件拷贝进行封装。
1、获取服务
腾讯COS对象存储,赠送了40个G的流量,很不幸的是我又买了10个G的流量包。
桶的列表
2、Java代码封装TxCosTemplate,操作腾讯COS对象存储
2.1 引入依赖
<!--腾讯COS-->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<scope>provided</scope>
</dependency>
2.2 HwObsTemplate代码
package com.toto.core.oss;
import cn.hutool.core.util.ObjectUtil;
import com.qcloud.cos.COSClient;
import com.qcloud.cos.http.HttpMethodName;
import com.qcloud.cos.model.CannedAccessControlList;
import com.qcloud.cos.model.ObjectMetadata;
import com.toto.core.oss.enums.UploadType;
import com.toto.core.oss.model.TotoFile;
import com.toto.core.oss.tool.OssUtil;
import lombok.AllArgsConstructor;
import org.springframework.web.multipart.MultipartFile;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description: TencentCosTemplate
* @Package: com.toto
* @Author gufanbiao
* @CreateTime 2024-06-01 12:59
*/
@SuppressWarnings("all")
@AllArgsConstructor
public class TxCosTemplate implements OssTemplate {
private final COSClient cosClient;
private final OssProperties ossProperties;
@Override
public void makeBucket(String bucketName) throws Exception {
if (!bucketExists(bucketName)) {
cosClient.createBucket(bucketName + "-" + ossProperties.getAppId());
cosClient.setBucketAcl(bucketName + "-" + ossProperties.getAppId(), CannedAccessControlList.PublicRead);
}
}
@Override
public void deleteBucket(String bucketName) throws Exception {
cosClient.deleteBucket(bucketName + "-" + ossProperties.getAppId());
}
@Override
public boolean bucketExists(String bucketName) throws Exception {
return cosClient.doesBucketExist(bucketName + "-" + ossProperties.getAppId());
}
@Override
public void copyFile(String bucketName, String fileName, String destBucketName) throws Exception {
cosClient.copyObject(bucketName + "-" + ossProperties.getAppId(), fileName, destBucketName + "-" + ossProperties.getAppId(), fileName);
}
@Override
public void copyFile(String bucketName, String fileName, String destBucketName, String destFileName) throws Exception {
cosClient.copyObject(bucketName + "-" + ossProperties.getAppId(), fileName, destBucketName + "-" + ossProperties.getAppId(), destFileName);
}
@Override
public TotoFile getFile(String fileName) throws Exception {
return getFile(ossProperties.getBucketName(), fileName);
}
@Override
public TotoFile getFile(String bucketName, String fileName) throws Exception {
ObjectMetadata fileInfo = cosClient.getObjectMetadata(bucketName + "-" + ossProperties.getAppId(), fileName);
TotoFile file = new TotoFile();
file.setFileName(fileName);
file.setFileUrl(fileUrl(file.getFileName()));
file.setHash(fileInfo.getContentMD5());
file.setFileSize(fileInfo.getContentLength());
file.setUploadTime(fileInfo.getLastModified());
file.setContentType(fileInfo.getContentType());
return file;
}
@Override
public String getPath(String fileName) throws Exception {
return getOssHost().concat("/").concat(fileName);
}
@Override
public String getPath(String bucketName, String fileName) throws Exception {
return getOssHost(bucketName).concat("/").concat(fileName);
}
@Override
public String fileUrl(String fileName) throws Exception {
return ossProperties.getEndpoint().concat("/").concat(ossProperties.getBucketName() + "-" + ossProperties.getAppId()).concat("/").concat(fileName);
}
@Override
public String fileUrl(String bucketName, String fileName) throws Exception {
return ossProperties.getEndpoint().concat("/").concat(bucketName + "-" + ossProperties.getAppId()).concat("/").concat(fileName);
}
@Override
public String getShortlytUrl(String bucketName, String fileName, Integer expires) throws Exception {
// 存储桶的命名格式为 BucketName-APPID,此处填写的存储桶名称必须为此格式
//String bucketName = "examplebucket-1250000000";
// 对象键(Key)是对象在存储桶中的唯一标识。详情请参见 [对象键](https://cloud.tencent.com/document/product/436/13324)
//String fileName = "exampleobject";
// 设置签名过期时间(可选), 若未进行设置则默认使用 ClientConfig 中的签名过期时间(1小时)
// 这里设置签名在半个小时后过期
Date expirationDate = new Date(System.currentTimeMillis() + expires * 60 * 1000); //分钟
// 填写本次请求的参数,需与实际请求相同,能够防止用户篡改此签名的 HTTP 请求的参数
Map<String, String> params = new HashMap<String, String>();
//params.put("param1", "value1");
// 填写本次请求的头部,需与实际请求相同,能够防止用户篡改此签名的 HTTP 请求的头部
Map<String, String> headers = new HashMap<String, String>();
//headers.put("header1", "value1");
// 请求的 HTTP 方法,上传请求用 PUT,下载请求用 GET,删除请求用 DELETE
HttpMethodName method = HttpMethodName.GET;
URL url = cosClient.generatePresignedUrl(bucketName+ "-" + ossProperties.getAppId(), fileName, expirationDate, method, headers, params);
return url.toString();
}
@Override
public TotoFile putFile(MultipartFile file) throws Exception {
return putFile(ossProperties.getBucketName(), file.getOriginalFilename(), file);
}
@Override
public TotoFile putFile(String fileName, MultipartFile file) throws Exception {
return putFile(ossProperties.getBucketName(), fileName, file);
}
@Override
public TotoFile putFile(String bucketName, String fileName, MultipartFile file) throws Exception {
return putFile(bucketName, fileName, file.getInputStream());
}
@Override
public TotoFile putFile(String fileName, InputStream stream) throws Exception {
return putFile(ossProperties.getBucketName(), fileName, stream);
}
@Override
public TotoFile putFile(String bucketName, String fileName, InputStream stream) throws Exception {
return putFile(bucketName, fileName, stream, "application/octet-stream", null);
}
@Override
public TotoFile putFile(String bucketName, String fileName, InputStream stream, MultipartFile file) throws Exception {
return putFile(bucketName, fileName, stream, "application/octet-stream", file);
}
private TotoFile putFile(String bucketName, String fileName, InputStream stream, String contentType, MultipartFile multipartFile) throws Exception {
boolean cover = false;
makeBucket(bucketName);
String originalName = fileName;
fileName = OssUtil.fileName(fileName);
ObjectMetadata objectMetadata = new ObjectMetadata();
//objectMetadata.setContentLength(100);
// 覆盖上传
cosClient.putObject(bucketName + "-" + ossProperties.getAppId(), fileName, stream, objectMetadata);
TotoFile file = new TotoFile();
file.setOriginalName(originalName);
file.setFileName(fileName);
file.setDomain(OssUtil.getOssHost(ossProperties,bucketName));
file.setFileUrl(fileUrl(bucketName, fileName));
file.setFileType(originalName.substring(originalName.lastIndexOf(".") + 1));
file.setUploadType(UploadType.OSS.getType());
if(ObjectUtil.isNotNull(multipartFile)){
file.setFileSize(multipartFile.getSize());
file.setContentType(multipartFile.getContentType());
file.setUploadTime(new Date());
}
return file;
}
@Override
public void deleteFile(String fileName) throws Exception {
cosClient.deleteObject(ossProperties.getBucketName() + "-" + ossProperties.getAppId(), fileName);
}
@Override
public void deleteFile(String bucketName, String fileName) throws Exception {
cosClient.deleteObject(bucketName + "-" + ossProperties.getAppId(), fileName);
}
@Override
public void deleteFiles(List<String> fileNames) throws Exception {
for (String fileName:fileNames) {
deleteFile(fileName);
}
}
@Override
public void deleteFiles(String bucketName, List<String> fileNames) throws Exception {
for (String fileName:fileNames) {
deleteFile(bucketName, fileName);
}
}
/**
* 获取域名
* @param bucketName 存储桶名称
* @return String
*/
public String getOssHost(String bucketName) {
return "http://" + cosClient.getClientConfig().getEndpointBuilder().buildGeneralApiEndpoint(bucketName + "-" + ossProperties.getAppId());
}
/**
* 获取域名
* @return String
*/
public String getOssHost() {
return getOssHost(ossProperties.getBucketName());
}
}
3.4 HwObsTest 代码
package com.toto;
import com.alibaba.fastjson.JSONObject;
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 com.toto.core.oss.OssProperties;
import com.toto.core.oss.TxCosTemplate;
import com.toto.core.oss.model.TotoFile;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
/**
* @Description: TencentCosTest
* @Package: com.toto
* @Author gufanbiao
* @CreateTime 2024-06-01 13:47
*/
@SuppressWarnings("all")
@SpringBootTest
public class TxCosTest {
//private static String ENDPOINT = "";
private static String ACCESS_KEY = "AKID0wqhdXVHX3jJxV6uiWH0mHJKWebOGHF5vf";
private static String SECRET_KEY = "tePJCFKOXYcbWXMJHA7GVi8XYuO1fEIJRRV";
private static String BUCKET_NAME = "toto-test";
private static String BUCKET_DEST_NAME = "toto-dest";
private static String APPID = "1302396640";
private static String REGION = "ap-beijing";
public static TxCosTemplate template() {
// 创建配置类
OssProperties ossProperties = new OssProperties();
//ossProperties.setEndpoint(ENDPOINT);
ossProperties.setAccessKey(ACCESS_KEY);
ossProperties.setSecretKey(SECRET_KEY);
ossProperties.setBucketName(BUCKET_NAME);
ossProperties.setAppId(APPID);
ossProperties.setRegion(REGION);
// 初始化用户身份信息(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层传输数据的超时时间,默认为60000毫秒。
clientConfig.setSocketTimeout(60000);
// 设置建立连接的超时时间,默认为60000毫秒。
clientConfig.setConnectionTimeout(60000);
// 设置从连接池中获取连接的超时时间(单位:毫秒),默认不超时。
clientConfig.setConnectionRequestTimeout(1000);
COSClient cosClient = new COSClient(credentials, clientConfig);
return new TxCosTemplate(cosClient, ossProperties);
}
/*********************************** mock对象信息 *****************************************/
private static String FILE_NAME = "你好世界.txt";
private static String CONTENT_TYPE = "text/plain";
private static String CONTENT = "你好世界!";
/**
* mock一个对象 使用Spring框架的MockMultipartFile类创建一个MultipartFile对象
* @return
* @throws IOException
*/
public static MultipartFile createMultipartFile() throws IOException {
return new MockMultipartFile(FILE_NAME, FILE_NAME, CONTENT_TYPE, CONTENT.getBytes());
}
/*********************************** 操作测试 *****************************************/
/**
* 创建 Bucket
*/
@Test
void testCreate() throws Exception {
template().makeBucket(BUCKET_NAME);
}
/**
* 删除 Bucket,桶不存在报错
*/
@Test
void deleteBucket() throws Exception {
template().deleteBucket(BUCKET_NAME);
}
/**
* 存储桶是否存在
*/
@Test
void bucketExists() throws Exception {
boolean b = template().bucketExists(BUCKET_NAME);
System.out.println("存储桶是否存在:" + b);
}
/**
* 上传文件 MultipartFile格式
* https://toto-test-1302396640.cos.ap-beijing.myqcloud.com/upload/2024-06-01/885aa533ed614dbb8e86f07591a40abb.txt
*/
@Test
void putFile1() throws Exception {
TotoFile totoFile = template().putFile(createMultipartFile());
System.out.println("上传文件对象封装:" + JSONObject.toJSON(totoFile));
}
/**
* 上传文件 文件流模式
*/
@Test
void putFile2() throws Exception {
InputStream inputStream = createMultipartFile().getInputStream();
TotoFile totoFile = template().putFile(FILE_NAME, inputStream);
System.out.println("上传文件对象封装:" + JSONObject.toJSON(totoFile));
}
/**
* 上传文件 文件流模式
*/
@Test
void putFile3() throws Exception {
TotoFile totoFile = template().putFile("hhhhhhh"+FILE_NAME, createMultipartFile());
System.out.println("上传文件对象封装:" + JSONObject.toJSON(totoFile));
}
/**
* 文件复制到另一个桶(文件名/路径不变)
* @throws Exception
*/
@Test
void copyFile1() throws Exception {
template().copyFile(BUCKET_NAME,"upload/2024-06-01/885aa533ed614dbb8e86f07591a40abb.txt",BUCKET_DEST_NAME);
}
/**
* 文件复制到另一个桶(文件名/路径变更)
* @throws Exception
*/
@Test
void copyFile2() throws Exception {
template().copyFile(BUCKET_NAME,"upload/2024-06-01/885aa533ed614dbb8e86f07591a40abb.txt",BUCKET_DEST_NAME,"upload/2024-06-01/2a78f1088ea54fd399246fc2778c836b.txt");
}
/**
* 获取文件信息
* @throws Exception
*/
@Test
void statFile1() throws Exception {
TotoFile totoFile = template().getFile("upload/2024-06-01/885aa533ed614dbb8e86f07591a40abb.txt");
System.out.println("获取文件对象信息:" + JSONObject.toJSONString(totoFile));
}
/**
* 获取文件信息(指定桶的名称)
* @throws Exception
*/
@Test
void statFile2() throws Exception {
TotoFile totoFile = template().getFile(BUCKET_NAME,"upload/2024-06-01/885aa533ed614dbb8e86f07591a40abb.txt");
System.out.println("获取文件对象信息:" + JSONObject.toJSONString(totoFile));
}
/**
* 获取文件路径信息(没有什么实质的参考,就是内部组装)
*/
@Test
void getPath1() throws Exception {
String path = template().getPath("upload/2024-06-01/885aa533ed614dbb8e86f07591a40abb.txt");
System.out.println("获取文件路径信息:" + path);
}
/**
* 获取文件路径信息(没有什么实质的参考,就是内部组装)
*/
@Test
void getPath2() throws Exception {
String path = template().getPath(BUCKET_NAME,"upload/2024-06-01/885aa533ed614dbb8e86f07591a40abb.txt");
System.out.println("获取文件路径信息:" + path);
}
/**
* 获取文件路径信息(没有什么实质的参考,就是内部组装)
*/
@Test
void getFileUrl1() throws Exception {
String fileUrl = template().fileUrl("upload/2024-06-01/885aa533ed614dbb8e86f07591a40abb.txt");
System.out.println("获取文件路径信息:" + fileUrl);
}
/**
* 获取文件路径信息(没有什么实质的参考,就是内部组装)
*/
@Test
void getFileUrl2() throws Exception {
String fileUrl = template().fileUrl(BUCKET_NAME,"upload/2024-06-01/885aa533ed614dbb8e86f07591a40abb.txt");
System.out.println("获取文件路径信息:" + fileUrl);
}
//@Test
//void getPolicyType() throws Exception {
// String policyType = template().getPolicyType(BUCKET_NAME, null);
// System.out.println("获取当前桶的策略:" + policyType);
//}
/**
* 删除文件,使用配置文件中的桶
* @throws Exception
*/
@Test
void deleteFile1() throws Exception {
template().deleteFile("upload/2024-06-01/885aa533ed614dbb8e86f07591a40abb.txt");
}
/**
* 删除文件指定桶
* @throws Exception
*/
@Test
void deleteFile2() throws Exception {
template().deleteFile(BUCKET_NAME,"upload/2024-06-01/ff2c2dae570a45c3b26f71ffd07bdb54.txt");
}
/**
* 批量删除,默认配置文件中的桶(貌似有点问题,有时候可以,有时候不行)
* @throws Exception
*/
@Test
void deleteFile3() throws Exception {
List<String> fileNames = new ArrayList<>();
fileNames.add("upload/2024-06-01/7325050ffcf346ddbdefd2740dfb4d62.txt");
fileNames.add("upload/2024-06-01/ff2c2dae570a45c3b26f71ffd07bdb54.txt");
template().deleteFiles(fileNames);
}
/**
* 获取临时地址,临时地址使用在私有写中,才能达到想要的效果
* @throws Exception
*/
@Test
void getShortlytUrl() throws Exception {
String shortlytUrl = template().getShortlytUrl(BUCKET_NAME, "upload/2024-06-01/16d2896faa2f4d7bbcb1a61d98999324.txt", 5);
System.out.println("文件临时地址" + shortlytUrl);
}
}