需求背景:
項(xiàng)目中需要上傳圖片。
存儲(chǔ)方式:
使用騰訊云的OSS組件。
代碼實(shí)現(xiàn):
1、使用騰訊云OSS需要使用的參數(shù)信息:
OSS的域名;
OSS的地域節(jié)點(diǎn);
OSS存儲(chǔ)桶的名稱(chēng);
OSS權(quán)限憑證;
OSS權(quán)限訪問(wèn)秘鑰;
OSS圖片存儲(chǔ)策略;
使用的縮略圖策略;
允許上傳的圖片類(lèi)型;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
@Data
@Component
@ConfigurationProperties(prefix = "oss.tencent")
public class TencentProperties {
/**域名*/
private String domain;
/**地域節(jié)點(diǎn)*/
private String region;
/**存儲(chǔ)桶名稱(chēng)*/
private String bucketName;
/**secretId*/
private String secretId;
/**secretKey*/
private String secretKey;
/**圖片策略*/
private String styleRule;
/**縮略圖策略*/
private String thumbnailStyleRule;
/**文件類(lèi)型*/
private List<String> fileTypes;
}
參數(shù)yml文件或者通過(guò)配置中心進(jìn)行配置
oss:
tencent:
domain:
region: ap-XXX
bucketName: XXX
secretId: XXXXXX
secretKey: XXXXXX
styleRule:
thumbnailStyleRule: "!Photo_Compression"
fileTypes: ## 允許上傳的文件類(lèi)型
- png
- jpg
- jpeg
- gif
- bmp
- svg
2、上傳圖片操作工具類(lèi)service
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
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.http.HttpProtocol;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import com.qcloud.cos.model.UploadResult;
import com.qcloud.cos.region.Region;
import com.qcloud.cos.transfer.TransferManager;
import com.qcloud.cos.transfer.TransferManagerConfiguration;
import com.qcloud.cos.transfer.Upload;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Assert;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Component("tencent")
public class TencentFileHandle implements FileStrategy {
@Autowired
TencentProperties tencentProperties;
// 創(chuàng)建 COSClient 實(shí)例,這個(gè)實(shí)例用來(lái)后續(xù)調(diào)用請(qǐng)求
COSClient createCOSClient() {
// 設(shè)置用戶身份信息。
// SECRETID 和 SECRETKEY 請(qǐng)登錄訪問(wèn)管理控制臺(tái) https://console.cloud.tencent.com/cam/capi 進(jìn)行查看和管理
String secretId = tencentProperties.getSecretId();
String secretKey = tencentProperties.getSecretKey();
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// ClientConfig 中包含了后續(xù)請(qǐng)求 COS 的客戶端設(shè)置:
ClientConfig clientConfig = new ClientConfig();
// 設(shè)置 bucket 的地域
// COS_REGION 請(qǐng)參照 https://cloud.tencent.com/document/product/436/6224
clientConfig.setRegion(new Region(tencentProperties.getRegion()));
// 設(shè)置請(qǐng)求協(xié)議, http 或者 https
// 5.6.53 及更低的版本,建議設(shè)置使用 https 協(xié)議
// 5.6.54 及更高版本,默認(rèn)使用了 https
clientConfig.setHttpProtocol(HttpProtocol.https);
// 以下的設(shè)置,是可選的:
// 設(shè)置 socket 讀取超時(shí),默認(rèn) 30s
clientConfig.setSocketTimeout(30*1000);
// 設(shè)置建立連接超時(shí),默認(rèn) 30s
clientConfig.setConnectionTimeout(30*1000);
// 如果需要的話,設(shè)置 http 代理,ip 以及 port
// clientConfig.setHttpProxyIp("httpProxyIp");
// clientConfig.setHttpProxyPort(80);
// 生成 cos 客戶端。
return new COSClient(cred, clientConfig);
}
// 創(chuàng)建 TransferManager 實(shí)例,這個(gè)實(shí)例用來(lái)后續(xù)調(diào)用高級(jí)接口
TransferManager createTransferManager() {
// 創(chuàng)建一個(gè) COSClient 實(shí)例,這是訪問(wèn) COS 服務(wù)的基礎(chǔ)實(shí)例。
// 詳細(xì)代碼參見(jiàn)本頁(yè): 簡(jiǎn)單操作 -> 創(chuàng)建 COSClient
COSClient cosClient = createCOSClient();
// 自定義線程池大小,建議在客戶端與 COS 網(wǎng)絡(luò)充足(例如使用騰訊云的 CVM,同地域上傳 COS)的情況下,設(shè)置成16或32即可,可較充分的利用網(wǎng)絡(luò)資源
// 對(duì)于使用公網(wǎng)傳輸且網(wǎng)絡(luò)帶寬質(zhì)量不高的情況,建議減小該值,避免因網(wǎng)速過(guò)慢,造成請(qǐng)求超時(shí)。
ExecutorService threadPool = Executors.newFixedThreadPool(32);
// 傳入一個(gè) threadpool, 若不傳入線程池,默認(rèn) TransferManager 中會(huì)生成一個(gè)單線程的線程池。
TransferManager transferManager = new TransferManager(cosClient, threadPool);
// 設(shè)置高級(jí)接口的配置項(xiàng)
// 分塊上傳閾值和分塊大小分別為 5MB 和 1MB
TransferManagerConfiguration transferManagerConfiguration = new TransferManagerConfiguration();
transferManagerConfiguration.setMultipartUploadThreshold(5*1024*1024);
transferManagerConfiguration.setMinimumUploadPartSize(1*1024*1024);
transferManager.setConfiguration(transferManagerConfiguration);
return transferManager;
}
void shutdownTransferManager(TransferManager transferManager) {
// 指定參數(shù)為 true, 則同時(shí)會(huì)關(guān)閉 transferManager 內(nèi)部的 COSClient 實(shí)例。
// 指定參數(shù)為 false, 則不會(huì)關(guān)閉 transferManager 內(nèi)部的 COSClient 實(shí)例。
transferManager.shutdownNow(true);
}
@Override
public UploadDto upload(MultipartFile file) throws Exception {
return upload(file, null);
}
@Override
public UploadDto upload(MultipartFile file, String filePath) throws Exception {
//文件名
String fileFullName = FileUtil.getName(file.getOriginalFilename());
InputStream inputStream = file.getInputStream();
return upload(inputStream, fileFullName, filePath);
}
public UploadDto upload(InputStream inputStream, String fileFullName, String filePath) throws Exception {
if (inputStream == null) {
throw new Exception("上傳文件不能為空");
}
TransferManager transferManager = createTransferManager();
String bucketName = tencentProperties.getBucketName();
//int inputStreamLength = 1024 * 1024;
// byte data[] = new byte[inputStreamLength];
// InputStream inputStream = new ByteArrayInputStream(data);
ObjectMetadata objectMetadata = new ObjectMetadata();
// 上傳的流如果能夠獲取準(zhǔn)確的流長(zhǎng)度,則推薦一定填寫(xiě) content-length
// 如果確實(shí)沒(méi)辦法獲取到,則下面這行可以省略,但同時(shí)高級(jí)接口也沒(méi)辦法使用分塊上傳了
//objectMetadata.setContentLength(inputStreamLength);
try {
//時(shí)間戳
String timestamp = String.valueOf(System.currentTimeMillis());
//文件擴(kuò)展名
String extension = FileUtil.getSuffix(fileFullName);
String fileName = FileUtil.getPrefix(fileFullName);
List<String> fileTypes = tencentProperties.getFileTypes();
if(fileTypes != null) {
boolean flag= fileTypes.contains(extension);
Assert.isTrue(flag, "不支持上傳的文件類(lèi)型:" + extension);
}
String upFilePath = StringUtils.join(fileName, "_", timestamp, ".", extension);
if(filePath != null) {
upFilePath = StringUtils.join(filePath, "/", upFilePath);
}
String key = upFilePath;
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, key, inputStream, objectMetadata);
// 高級(jí)接口會(huì)返回一個(gè)異步結(jié)果Upload
// 可同步地調(diào)用 waitForUploadResult 方法等待上傳完成,成功返回UploadResult, 失敗拋出異常
Upload upload = transferManager.upload(putObjectRequest);
UploadResult uploadResult = upload.waitForUploadResult();
if (uploadResult == null) {
log.error("上傳附件到騰訊云失敗 fileName={}", upFilePath);
throw new Exception("上傳附件 " + upFilePath + " 到騰訊云失敗 ");
}
log.info("cos fileName:" + upFilePath);
//返回上傳結(jié)果
UploadDto uploadDto = new UploadDto();
uploadDto.setName(upFilePath);
// uploadDto.setKey(upFilePath);
uploadDto.setCreateTime(DateUtil.date());
return uploadDto;
} catch (Exception e) {
log.error("cos 上傳失敗", e);
throw new RuntimeException("文件="+fileFullName + " 上傳失敗");
} finally {
shutdownTransferManager(transferManager);
}
}
@Override
public byte[] download(String key) throws Exception {
return null;
}
@Override
public void delete(String key) {
}
}
import java.io.Serializable;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
@Data
public class UploadDto implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
/**圖片名*/
private String name;
/**圖片路徑*/
private String imgUrl;
/**上傳日期*/
@JsonFormat(pattern = "yyyy-MM-dd")
private Date createTime;
}
3、maven需要引入的騰訊云OSS依賴(lài)
<!--cos -->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.89</version>
</dependency>
-------------------
騰訊云OSS(Object Storage Service)是一種基于對(duì)象的存儲(chǔ)服務(wù),提供高可用、高可靠、低成本、可擴(kuò)展的存儲(chǔ)資源。以下是騰訊云OSS的原理與使用:
一、騰訊云OSS原理
- 分布式存儲(chǔ)架構(gòu)
騰訊云OSS采用分布式存儲(chǔ)架構(gòu),將數(shù)據(jù)分散存儲(chǔ)在多個(gè)節(jié)點(diǎn)上,以提高數(shù)據(jù)的可靠性和可用性。每個(gè)節(jié)點(diǎn)都采用副本冗余的方式進(jìn)行數(shù)據(jù)備份,確保數(shù)據(jù)不會(huì)因?yàn)槟硞€(gè)節(jié)點(diǎn)故障而丟失。同時(shí),通過(guò)分布式負(fù)載均衡技術(shù),將數(shù)據(jù)均勻分布在各個(gè)節(jié)點(diǎn)上,提高數(shù)據(jù)訪問(wèn)的效率和穩(wěn)定性。
- 數(shù)據(jù)冗余與容錯(cuò)
騰訊云OSS采用數(shù)據(jù)冗余和容錯(cuò)技術(shù),確保數(shù)據(jù)的可靠性和可用性。在分布式存儲(chǔ)架構(gòu)中,每個(gè)數(shù)據(jù)塊都會(huì)備份多個(gè)副本,分布在不同的節(jié)點(diǎn)上,確保即使某個(gè)節(jié)點(diǎn)發(fā)生故障,其他節(jié)點(diǎn)上的副本仍然可用。此外,騰訊云OSS還采用數(shù)據(jù)校驗(yàn)技術(shù),對(duì)數(shù)據(jù)進(jìn)行冗余校驗(yàn),檢測(cè)數(shù)據(jù)是否損壞或丟失。
- 數(shù)據(jù)加密與安全保護(hù)
騰訊云OSS采用數(shù)據(jù)加密和安全保護(hù)技術(shù),確保數(shù)據(jù)的安全性。在數(shù)據(jù)傳輸過(guò)程中,騰訊云OSS采用SSL/TLS加密技術(shù),對(duì)數(shù)據(jù)進(jìn)行加密傳輸,防止數(shù)據(jù)被竊取或篡改。在數(shù)據(jù)存儲(chǔ)時(shí),騰訊云OSS采用加密技術(shù)對(duì)數(shù)據(jù)進(jìn)行加密存儲(chǔ),確保數(shù)據(jù)在存儲(chǔ)時(shí)不會(huì)被竊取或篡改。
二、騰訊云OSS使用
- 注冊(cè)與登錄騰訊云OSS
首先需要注冊(cè)騰訊云賬號(hào)并登錄到騰訊云控制臺(tái),然后在服務(wù)列表中找到并選擇“對(duì)象存儲(chǔ)服務(wù)(OSS)”。
- 創(chuàng)建存儲(chǔ)空間
在騰訊云OSS控制臺(tái)中,可以選擇創(chuàng)建新的存儲(chǔ)空間。填寫(xiě)存儲(chǔ)空間的名稱(chēng)、選擇地域和存儲(chǔ)類(lèi)型等信息,并設(shè)置訪問(wèn)權(quán)限和安全策略等。
- 上傳文件
在騰訊云OSS控制臺(tái)中,可以上傳文件到創(chuàng)建的存儲(chǔ)空間中。可以選擇上傳本地文件或直接上傳文件流。在上傳文件時(shí),可以選擇文件的名稱(chēng)、存儲(chǔ)類(lèi)型和訪問(wèn)權(quán)限等信息。
- 下載文件
在騰訊云OSS控制臺(tái)中,可以下載存儲(chǔ)空間中的文件。可以選擇下載文件的名稱(chēng)、下載路徑和下載方式等信息。同時(shí),也可以設(shè)置下載文件的訪問(wèn)權(quán)限和有效期等。
- 刪除文件
在騰訊云OSS控制臺(tái)中,可以刪除存儲(chǔ)空間中的文件。選擇要?jiǎng)h除的文件名稱(chēng),點(diǎn)擊刪除即可。需要注意的是,刪除的文件將無(wú)法恢復(fù),請(qǐng)謹(jǐn)慎操作。
- 配置CDN加速
為了提高文件的訪問(wèn)速度,可以在騰訊云OSS控制臺(tái)中配置CDN加速服務(wù)。配置完成后,將通過(guò)CDN節(jié)點(diǎn)加速訪問(wèn)存儲(chǔ)空間中的文件??梢蕴岣呶募捻憫?yīng)速度和可擴(kuò)展性。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-510034.html
以上是騰訊云OSS的原理與使用簡(jiǎn)介,供您參考。如需獲取更多詳細(xì)信息,建議訪問(wèn)騰訊云官網(wǎng)或咨詢其官方客服人員。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-510034.html
到了這里,關(guān)于JAVA開(kāi)發(fā)(騰訊云OSS圖片上傳)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!