云存储之腾讯COS——基础操作
云存储之腾讯COS——基础操作)目录官方地址依赖引入yml文件配置配置类实现XML解析工具类文件处理工具目录官方地址COS对象存储COS-demo-Github依赖引入<!-- tencent COS --><dependency><groupId>com.qcloud</groupId><artifactId>cos_api</a
·
目录
官方地址
依赖引入
<!-- tencent COS -->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.54</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.tencentcloudapi</groupId>
<artifactId>tencentcloud-sdk-java</artifactId>
<!-- go to https://search.maven.org/search?q=tencentcloud-sdk-java and get the latest version. -->
<!-- 请到https://search.maven.org/search?q=tencentcloud-sdk-java查询所有版本,最新版本如下 -->
<version>3.1.322</version>
</dependency>
<!--xml解析工具 解析媒体数据-->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
yml文件配置
#腾讯cos 存储
tencent:
cos:
secretId:
secretKey:
region:
baseUrl:
bucket:
配置类
ConfigurationProperties(prefix = "tencent.cos")
@Component
public class TencentCosConfig {
/**腾讯云的SecretId*/
public static String secretId;
/**腾讯云的SecretKey*/
public static String secretKey;
/**腾讯云的bucket (存储桶)*/
public static String bucket;
/**腾讯云的region(bucket所在地区)*/
public static String region;
/**腾讯云的allowPrefix(允许上传的路径)*/
public static String allowPrefix = "*";
/**腾讯云的临时密钥时长(单位秒)*/
public static String durationSeconds;
/**腾讯云的访问基础链接:*/
public static String baseUrl;
public void setSecretId(String secretId) {
TencentCosConfig.secretId = secretId;
}
public void setSecretKey(String secretKey) {
TencentCosConfig.secretKey = secretKey;
}
public void setBucket(String bucket) {
TencentCosConfig.bucket = bucket;
}
public void setRegion(String region) {
TencentCosConfig.region = region;
}
public void setAllowPrefix(String allowPrefix) {
TencentCosConfig.allowPrefix = allowPrefix;
}
public void setDurationSeconds(String durationSeconds) {
TencentCosConfig.durationSeconds = durationSeconds;
}
public void setBaseUrl(String baseUrl) {
TencentCosConfig.baseUrl = baseUrl;
}
}
实现
@Slf4j
public class TencentCosUtils {
/**
* 桶的名称
*/
static String bucketName = TencentCosConfig.bucket;
static COSCredentials cred ;
static ClientConfig clientConfig ;
static COSClient cosClient ;
static Region region;
static {
// 1 初始化用户身份信息(secretId, secretKey)
cred = new BasicCOSCredentials(TencentCosConfig.secretId, TencentCosConfig.secretKey);
// 2 设置 bucket 的地域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
// clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
region = new Region(TencentCosConfig.region);
clientConfig = new ClientConfig(region);
clientConfig.setHttpProtocol(HttpProtocol.https);
// 3 生成 cos 客户端。
cosClient = new COSClient(cred, clientConfig);
}
/**
* 初始化CosClient
* @return client
*/
public static COSClient initCosClient(){
// 1 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(TencentCosConfig.secretId, TencentCosConfig.secretKey);
// 2 设置 bucket 的地域, COS 地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
// clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题 Java SDK 部分。
Region region = new Region(TencentCosConfig.region);
ClientConfig clientConfig = new ClientConfig(region);
clientConfig.setHttpProtocol(HttpProtocol.https);
// 3 生成 cos 客户端。
return new COSClient(cred, clientConfig);
}
/**
* 上传
* @param srcFilePath 源文件路径
* @param targetFilePath 目标文件路径
* @return 云访问路径
*/
public static String upload(String srcFilePath, String targetFilePath){
Assert.notNull(srcFilePath, "上传文件路径为空!");
// 处理文件路径
srcFilePath = srcFilePath.startsWith("/") ? srcFilePath : "/" + srcFilePath;
targetFilePath = ObjectUtils.isEmpty(targetFilePath) ? FileUploadUtils.extractFilename(srcFilePath) : targetFilePath;
targetFilePath = targetFilePath.startsWith("/") ? targetFilePath : "/" + targetFilePath;
targetFilePath = addFilePre(targetFilePath);
String result = null;
try{
// 指定要上传的文件
File localFile = new File(srcFilePath);
// 指定文件上传到 COS 上的路径,即对象键。例如对象键为folder/picture.jpg,则表示将文件 picture.jpg 上传到 folder 路径下
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, targetFilePath, localFile);
PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
log.info("腾讯上传文件成功:{}", putObjectResult.getETag());
result = TencentCosConfig.baseUrl + targetFilePath;
} catch (CosClientException e) {
//失败,抛出 CosServiceException
e.printStackTrace();
}
return result;
}
/**
* 字节流上传
* @param file 文件
* @param filePath 目标文件路径
* @return 云访问路径
*/
public static String upload(MultipartFile file, String filePath){
Assert.notNull(file, "上传文件为空!");
log.info("开始上传文件:" + filePath);
// 处理文件路径
filePath = ObjectUtils.isEmpty(filePath) ? FileUploadUtils.extractFilename(file) : filePath;
filePath = filePath.startsWith("/") ? filePath : "/" + filePath;
filePath = addFilePre(filePath);
String resultUrl = null;
try{
byte[] bytes = file.getBytes();
//文件大小 建议不超过2M
int length = bytes.length;
// 获取文件流
InputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
ObjectMetadata objectMetadata = new ObjectMetadata();
// 从输入流上传必须制定content length, 否则http客户端可能会缓存所有数据,存在内存OOM的情况
objectMetadata.setContentLength(length);
// 默认下载时根据cos路径key的后缀返回响应的contenttype, 上传时设置contenttype会覆盖默认值
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, filePath, byteArrayInputStream, objectMetadata);
PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
log.info("腾讯上传文件成功:{}",putObjectResult.getETag());
resultUrl = TencentCosConfig.baseUrl + filePath;
} catch (CosClientException | IOException e) {
//失败,抛出 CosServiceException
e.printStackTrace();
}
return resultUrl;
}
/**
* 删除文件 自动判断文件是否存在
* @param filePath 文件名
*/
public static void delete(String filePath){
Assert.notNull(filePath, "删除文件路径为空!");
try {
cosClient.deleteObject(bucketName, filePath);
log.info("文件删除成功");
} catch (CosClientException serverException) {
serverException.printStackTrace();
}
}
/**
* 下载到指定文件
* @param srcFilePath 源文件路径
* @param targetFilePath 目标文件路径
*/
public static void downloadSingle(String srcFilePath, String targetFilePath){
Assert.notNull(srcFilePath, "下载源文件路径为空!");
Assert.notNull(srcFilePath, "下载目标文件路径为空!");
try{
// 下载到指定的本地路径
if(ObjectUtils.isEmpty(srcFilePath) || ObjectUtils.isEmpty(targetFilePath)) {
throw new CustomException("下载路径为空");
}
GetObjectRequest getObjectRequest = new GetObjectRequest(bucketName, srcFilePath);
ObjectMetadata downObjectMeta = cosClient.getObject(getObjectRequest, new File(targetFilePath));
} catch (CosClientException serverException) {
serverException.printStackTrace();
}
}
/**
* 下载文件流
* @param filePath 文件路径
*/
public static void downloadSingle(String filePath, HttpServletResponse response){
String fileName = FileUtils.getName(filePath);
try{
COSObject cosObject = cosClient.getObject(bucketName, filePath);
InputStream in = cosObject.getObjectContent();
//设置文件名
FileUtils.setAttachmentResponseHeader(response, fileName);
//读取文件流
ServletOutputStream outputStream = response.getOutputStream();
IoUtils.copy(in, outputStream);
outputStream.close();
in.close();
} catch (CosClientException | IOException serverException) {
serverException.printStackTrace();
}
}
/**
* copyObject最大支持5G文件的copy
* 支持跨桶 跨区域
* @param reg 区域
* @param srcBucketName 源bucket, bucket名需包含appid
* @param srcKey 要拷贝的源文件路径
* @param destBucketName 目的bucket, bucket名需包含appid
* @param destKey 要拷贝的目的文件路径
*/
public static void copySmallFile(String reg, String srcBucketName, String srcKey, String destBucketName, String destKey) {
Region region = new Region(reg);
CopyObjectRequest copyObjectRequest = new CopyObjectRequest(region, srcBucketName,
srcKey, destBucketName, destKey);
try {
log.info("开始文件复制:源路径{},目的路径{}",srcKey, destKey);
CopyObjectResult copyObjectResult = cosClient.copyObject(copyObjectRequest);
log.info("完成文件复制:源路径{},目的路径{}",srcKey, destKey);
//crc64 可以验证数据的完整性
String crc64 = copyObjectResult.getCrc64Ecma();
} catch (CosClientException e) {
e.printStackTrace();
}
}
/**
* 获取媒体数据
* @param filePath 文件路径
* @return Media
*/
public static MediaInfoVO getMetaInfo(String filePath){
filePath = filePath.contains("com") ? filePath : TencentCosConfig.baseUrl + FileUtils.SLASH + filePath;
String getUrl = filePath + "?ci-process=videoinfo";
MediaInfoVO mediaInfoVO = new MediaInfoVO();
try {
//1·获取MediaInfo 主体数据
JSONObject jsonObject = TencentApiUtils.doGet(getUrl);
log.info("mediaInfo1{}",jsonObject.getJSONArray("MediaInfo").toJSONString());
//2·获取format 数据
Object formatObject = jsonObject.getJSONArray("MediaInfo").getJSONObject(0).
getJSONArray("Format").get(0);
MediaFormatVO format = JSON.parseObject(JSONObject.toJSONString(formatObject), MediaFormatVO.class);
//时长为0 格式不正确
if(Objects.isNull(format.getDuration())){
format.setDuration(-1f);
}
mediaInfoVO.setFormat(format);
//3·获取stream 数据 目前不使用 详细流数据
if(!Objects.isNull(formatObject)){
return mediaInfoVO;
}
JSONObject streamJson = jsonObject.getJSONArray("MediaInfo")
.getJSONObject(0).getJSONArray("Stream").getJSONObject(0);
MediaStreamVO stream = new MediaStreamVO();
//视频
Object videObject = streamJson.getJSONArray("Video");
if(!Objects.isNull(videObject)){
videObject = streamJson.getJSONArray("Video").get(0);
stream.setVideo(JSON.parseObject(JSONObject.toJSONString(videObject), MediaVideoVO.class));
}
//音频
Object audioObject = streamJson.getJSONArray("Audio");
if(!Objects.isNull(audioObject)){
audioObject = streamJson.getJSONArray("Audio").get(0);
stream.setAudio(JSON.parseObject(JSONObject.toJSONString(audioObject), MediaAudioVO.class));
}
//字幕
Object subtitleObject = streamJson.getJSONArray("Subtitle");
if(!Objects.isNull(subtitleObject)){
subtitleObject = streamJson.getJSONArray("Subtitle").get(0);
stream.setSubtitle(JSON.parseObject(JSONObject.toJSONString(subtitleObject), MediaSubtitleVO.class));
}
mediaInfoVO.setStream(stream);
log.info("mediaInfo{}}",JSONObject.toJSONString(mediaInfoVO));
} catch (IOException e) {
log.info("获取媒体数据错误{}", e.getMessage());
}
return mediaInfoVO;
}
}
XML解析工具类
import java.util.List;
import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class StringAnalysisXml {
/**
* String 转 org.dom4j.Document
* @param xml
* @return
* @throws DocumentException
*/
public static Document strToDocument(String xml){
try {
//加上xml标签是为了获取最外层的标签,如果不需要可以去掉
return DocumentHelper.parseText(xml);
} catch (DocumentException e) {
return null;
}
}
/**
* org.dom4j.Document 转 com.alibaba.fastjson.JSONObject
* @param xml
* @return
* @throws DocumentException
*/
public static JSONObject documentToJSONObject(String xml){
return elementToJSONObject(strToDocument(xml).getRootElement());
}
/**
* org.dom4j.Element 转 com.alibaba.fastjson.JSONObject
* @param node
* @return
*/
public static JSONObject elementToJSONObject(Element node) {
JSONObject result = new JSONObject();
// 当前节点的名称、文本内容和属性
List<Attribute> listAttr = node.attributes();// 当前节点的所有属性的list
for (Attribute attr : listAttr) {// 遍历当前节点的所有属性
result.put(attr.getName(), attr.getValue());
}
// 递归遍历当前节点所有的子节点
List<Element> listElement = node.elements();// 所有一级子节点的list
if (!listElement.isEmpty()) {
for (Element e : listElement) {// 遍历所有一级子节点
if (e.attributes().isEmpty() && e.elements().isEmpty()) // 判断一级节点是否有属性和子节点
result.put(e.getName(), e.getTextTrim());// 沒有则将当前节点作为上级节点的属性对待
else {
if (!result.containsKey(e.getName())) // 判断父节点是否存在该一级节点名称的属性
result.put(e.getName(), new JSONArray());// 没有则创建
((JSONArray) result.get(e.getName())).add(elementToJSONObject(e));// 将该一级节点放入该节点名称的属性对应的值中
}
}
}
return result;
}
}
文件处理工具
/**
* 返回文件名
*
* @param filePath 文件
* @return 文件名
*/
public static String getName(String filePath)
{
if (null == filePath)
{
return null;
}
int len = filePath.length();
if (0 == len)
{
return filePath;
}
if (isFileSeparator(filePath.charAt(len - 1)))
{
// 以分隔符结尾的去掉结尾分隔符
len--;
}
int begin = 0;
char c;
for (int i = len - 1; i > -1; i--)
{
c = filePath.charAt(i);
if (isFileSeparator(c))
{
// 查找最后一个路径分隔符(/或者\)
begin = i + 1;
break;
}
}
return filePath.substring(begin, len);
}
/**
* 下载文件名重新编码
*
* @param response 响应对象
* @param realFileName 真实文件名
* @return
*/
public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
{
String percentEncodedFileName = percentEncode(realFileName);
StringBuilder contentDispositionValue = new StringBuilder();
contentDispositionValue.append("attachment; filename=")
.append(percentEncodedFileName)
.append(";")
.append("filename*=")
.append("utf-8''")
.append(percentEncodedFileName);
response.setHeader("Content-disposition", contentDispositionValue.toString());
}
/**
* 编码文件名
*/
public static final String extractFilename(MultipartFile file)
{
String fileName = file.getOriginalFilename();
String extension = getExtension(file);
fileName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
return fileName;
}
/**
* 微信 API get请求
* @param url 请求路径
* @return Object
* @throws IOException io
*/
public static JSONObject doGet(String url) throws IOException {
JSONObject jsonObject = null;
HttpClient client = HttpClientBuilder.create().build();
final HttpGet httpGet = new HttpGet(url);
HttpResponse response = client.execute(httpGet);
HttpEntity entity = response.getEntity();
if (entity != null) {
// 返回结果转化为JSON对象
final String result = EntityUtils.toString(entity, "UTF-8");
jsonObject = StringAnalysisXml.documentToJSONObject(result);
}
return jsonObject;
}
更多推荐
已为社区贡献3条内容
所有评论(0)