SpringBoot集成腾讯COS流程
1.pom.xml中添加cos配置
<!--腾讯cos -->
<dependency><groupId>com.qcloud</groupId><artifactId>cos_api</artifactId><version>5.6.28</version>
</dependency>
2.application.yaml中添加cos配置
# 腾讯云存储cos相关公共配置
tencent:cos:secretId: ABIDFG5gz36gMp2xbyHvYw3usecretKey: 93ima8OcaHhDUUDjEdmfYEdbucketName: haha-18888888folder: videoregion: ap-shanghai
3.创建属性映射类CosProperties
/*** Cos配置*/
@Data
@Component
@RefreshScope
@ConfigurationProperties(prefix = "tencent.cos")
public class CosProperties {private String secretId;private String secretKey;private String bucketName;private String folder;private String region;}
4.封装Cos工具类
/*** cos 工具类*/
@Slf4j
public class CosUtils {private static CosUtils cosUtils = new CosUtils();private COSClient cosClient;public static CosUtils getInstance() {return cosUtils;}private CosProperties cosProperties;public CosUtils setCosProperties(CosProperties cosProperties) {this.cosProperties = cosProperties;this.cosClient = createCOSClient(cosProperties);return this;}public String getUploadTemporaryToken(String key) {if (StrUtil.hasBlank(cosProperties.getSecretId(), cosProperties.getSecretKey())) {return null;}COSCredentials cred = new BasicCOSCredentials(cosProperties.getSecretId(), cosProperties.getSecretKey());COSSigner signer = new COSSigner();// 设置过期时间为1个小时LocalDateTime now = LocalDateTime.now();Date expiredTime = new Date(now.toInstant(ZoneOffset.of("+8")).toEpochMilli() + 3600L * 1000L);// 要签名的 key, 生成的签名只能用于对应此 key 的上传log.info("待签名key[{}], now[{}]", key, now);String signStr = signer.buildAuthorizationStr(HttpMethodName.PUT, key, cred, expiredTime);log.info("签名成功, key[{}], now[{}], signStr[{}]", key, now, signStr);return signStr;}/*** 上传文件* 1.创建本地文件 2.上传** @param fileName 文件名(带后缀)* @param fileContent 文件内容* @return*/public String upload(String fileName, String fileContent, String customizeFolder) {try {String cosSecretId = cosProperties.getSecretId();String cosSecretKey = cosProperties.getSecretKey();String folder = StringUtils.isEmpty(customizeFolder) ? cosProperties.getFolder() : customizeFolder;String bucketName = cosProperties.getBucketName();if (StringUtils.isEmpty(cosSecretId) ||StringUtils.isEmpty(cosSecretKey) ||StringUtils.isEmpty(bucketName) ||StringUtils.isEmpty(folder)) {log.error("cos upload params Incomplete");return "";}String root = Objects.requireNonNull(CosUtils.class.getResource("/")).getPath();String s = root + "/temp/upload/";File localFile = getLocalFile(fileContent, s, fileName);if (localFile == null) {return "";}DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");String fromatDate = LocalDateTime.now().format(formatter);String fileUrl = folder + "/" + fromatDate + "/" + fileName;PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileUrl, localFile);// 设置存储类型, 默认是标准(Standard), 低频(standard_ia)putObjectRequest.setStorageClass(StorageClass.Standard);try {this.cosClient.putObject(putObjectRequest);} catch (CosClientException e) {log.error("An exception occurs during execution cos upload,error message:{}", e.getMessage());}//删除本地缓存文件if (localFile.exists()) {localFile.delete();}return fileUrl.startsWith("/") ? fileUrl : "/" + fileUrl;}catch (Exception e){log.error("文件上传失败,{}",e);}return StrUtil.EMPTY;}/*** 删除文件** @param bucketName* @param key* @return*/public Boolean deleteCosFile(String bucketName, String key) {String cosSecretId = cosProperties.getSecretId();String cosSecretKey = cosProperties.getSecretKey();Boolean executeFlag = true;if (StringUtils.isEmpty(cosSecretId) ||StringUtils.isEmpty(cosSecretKey) ||StringUtils.isEmpty(bucketName) ||StringUtils.isEmpty(key)) {log.error("cos delete file params Incomplete");return false;}COSCredentials cred = new BasicCOSCredentials(cosSecretId, cosSecretKey);// 2 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224ClientConfig clientConfig = new ClientConfig(new Region("ap-nanjing"));// 3 生成cos客户端COSClient cosclient = new COSClient(cred, clientConfig);try {cosclient.deleteObject(bucketName, key);} catch (CosClientException e) {log.error("An exception occurs during execution cos delete,error message:{}", e.getMessage());executeFlag = false;}// 关闭客户端cosclient.shutdown();return executeFlag;}private void getDir(String path) {File localFile = new File(path);if (!localFile.exists()) {localFile.mkdirs();}}private File getLocalFile(String instructionSet, String dir, String fileName) {File localFile = null;try {getDir(dir);localFile = new File(dir, fileName);if (!localFile.exists()) {localFile.createNewFile();}FileOutputStream fos = new FileOutputStream(localFile, true);OutputStreamWriter osw = new OutputStreamWriter(fos);BufferedWriter bw = new BufferedWriter(osw);bw.write(instructionSet);bw.newLine();bw.flush();bw.close();osw.close();fos.close();return localFile;} catch (IOException e2) {log.error("An exception occurs during execution create local file,error message:{} ", e2.getMessage());return null;}}/*** 获取二进制文件*/public static byte[] downLoadBinary(String urlStr) throws IOException {HttpURLConnection conn = null;InputStream inputStream = null;ByteArrayOutputStream bos = null;try {URL url = new URL(urlStr);conn = (HttpURLConnection) url.openConnection();//设置超时间为10秒conn.setConnectTimeout(10 * 1000);conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36");//得到输入流inputStream = conn.getInputStream();bos = new ByteArrayOutputStream();//获取数据数组return readInputStream(inputStream, bos);} finally {if (bos != null) {bos.close();}if (inputStream != null) {inputStream.close();}if (conn != null) {conn.disconnect();}}}/*** 获取字符串列表*/public static List<String> downLoadList(String urlStr) throws IOException {HttpURLConnection conn = null;InputStream inputStream = null;try {URL url = new URL(urlStr);conn = (HttpURLConnection) url.openConnection();//设置超时间为10秒conn.setConnectTimeout(10 * 1000);conn.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.135 Safari/537.36");//得到输入流inputStream = conn.getInputStream();//获取数据数组 windows操作系统默认编码:GB18030return IoUtil.readLines(new InputStreamReader(inputStream, Charset.forName("GB18030")), new ArrayList<>());} catch (IOException e){log.error("An exception occurs during execution download file,error message:{} ", e.getMessage());return Collections.EMPTY_LIST;}finally {if (inputStream != null) {inputStream.close();}if (conn != null) {conn.disconnect();}}}/*** 输入流转二进制*/public static byte[] readInputStream(InputStream inputStream, ByteArrayOutputStream bos) throws IOException {byte[] buffer = new byte[1024];int len = 0;while ((len = inputStream.read(buffer)) != -1) {bos.write(buffer, 0, len);}return bos.toByteArray();}/*** 创建cosClient** @param cosProperties* @return*/public static COSClient createCOSClient(CosProperties cosProperties) {// 1 初始化用户身份信息(secretId, secretKey)。// SECRETID和SECRETKEY请登录访问管理控制台 https://console.cloud.tencent.com/cam/capi// 进行查看和管理String secretId = cosProperties.getSecretId();String secretKey = cosProperties.getSecretKey();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(cosProperties.getRegion());ClientConfig clientConfig = new ClientConfig(region);// 这里建议设置使用 https 协议// 从 5.6.54 版本开始,默认使用了 httpsclientConfig.setHttpProtocol(HttpProtocol.https);// 3 生成 cos 客户端。return new COSClient(cred, clientConfig);}/*** 获取视频属性: (宽度、高度、时长)* 获取方式:从oss获取** @param ossUrl* @return*/public VideoProperties getVideoPropertiesFromCos(String ossUrl) {try {// 此处的key为对象键,对象键是对象在存储桶内的唯一标识String key = ossUrl;GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest("greatpan-1300159541", key, HttpMethodName.GET);// 设置签名过期时间(可选), 若未进行设置, 则默认使用 ClientConfig 中的签名过期时间(1小时)// 可以设置任意一个未来的时间,推荐是设置 10 分钟到 3 天的过期时间// 这里设置签名在半个小时后过期Date expirationDate = new Date(System.currentTimeMillis() + 30L * 60L * 1000L);req.setExpiration(expirationDate);req.addRequestParameter("ci-process", "videoinfo");URL url = this.cosClient.generatePresignedUrl(req);String mediaInfoXml = HttpClientUtil.doGet(url.toString());if (mediaInfoXml != null) {Document document = XmlUtil.readXML(mediaInfoXml);Node error = document.getElementsByTagName("Error").item(0);if (!ObjectUtils.isEmpty(error)) {Node message = document.getElementsByTagName("Message").item(0);log.error("获取视频基础信息出错.ossurl:{}, e:{}", ossUrl, Optional.ofNullable(message).map(Node::getTextContent).orElse(""));return null;}String width = document.getElementsByTagName("Width").item(0).getTextContent();String height = document.getElementsByTagName("Height").item(0).getTextContent();String rotation = document.getElementsByTagName("Rotation").item(0).getTextContent();if (StringUtils.isEmpty(width) || StringUtils.isEmpty(height) || StringUtils.isEmpty(rotation)) {return null;}VideoProperties videoProperties = new VideoProperties();int w = Integer.parseInt(width);int h = Integer.parseInt(height);int r = (int) Double.parseDouble(rotation);// 如果r是90或者270, 说明视频有旋转操作, 并宽高比有变化,需要把w 和 h 调换if (r % 90 == 0 && (r / 90 % 2) == 1) {videoProperties.setHeight(w);videoProperties.setWidth(h);return videoProperties;}videoProperties.setHeight(h);videoProperties.setWidth(w);return videoProperties;}return null;} catch (Exception e) {log.error("获取视频基础信息出错.ossurl:{}, e:", ossUrl, e);return null;}}public static void main(String[] args) throws Exception {
// VideoProperties videoPropertiesFromCos = getVideoPropertiesFromCos("/video/2024-05-30/723d5de3-f874-4744-819f-0a31e6e8e507.mp4");
// System.out.println(videoPropertiesFromCos);byte[] bytes = CosUtils.downLoadBinary("http://fs.haha.com/video/2024-05-30/1484098659191754752.txt");System.out.println(new String(bytes));}
}
5.前端获取cos上传token
@Resource
private CosUtils cosUtils;@GetMapping("/token")
@ApiOperation("获取文件存储token")
public ApiResponse<?> getFileUploadToken(@RequestParam String fileFullPath) {if(StringUtils.isEmpty(fileFullPath)){return ApiResponse.error("参数错误");}return ApiResponse.ok(cosUtils.getUploadTemporaryToken(fileFullPath));
}
相关文章:

SpringBoot集成腾讯COS流程
1.pom.xml中添加cos配置 <!--腾讯cos --> <dependency><groupId>com.qcloud</groupId><artifactId>cos_api</artifactId><version>5.6.28</version> </dependency> 2.application.yaml中添加cos配置 # 腾讯云存储cos…...

中高级前端开发岗
定位: 日常迭代任务的核心研发,具备高质、高效完成迭代任务的能力。 素质要求: 业务专家或擅长某一方向技术;有较丰富的开发经验;需要具备良好的沟通和协作能力,能够与其他部门和团队进行有效的沟通和协…...

idea常用配置
文章目录 I 常见问题1.1 取消maven忽略文件清单1.2 源根之外的java文件1.3 idea取消所有断点1.4 idea使用非模式提交界面1.5 用Service窗口展示所有服务及端口1.6 idea编码问题(加载配置文件失败)II idea 换行后自动缩进4个空格,怎么取消?I 常见问题 1.1 取消maven忽略文件…...

Spring AOP 切面按照一定规则切片并行查询Mapper并返回
需求: 有时候我们在查询mapper层时,有时候可能由于入参数据过大或者查询的范围较大,导致查询性能较慢,此时 我们需要将原本的查询按照一定规则将查询范围进行切面,然后分片查询,最后将查询结果进行组装合并…...

【vue3|第4期】Vue3的选项式与组合式
日期:2024年5月30日 作者:Commas 签名:(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释:如果您觉得有所帮助,帮忙点个赞,也可以关注我,我们一起成长;如果有不对的地方…...

算法训练营第四十五天 | LeetCode 1049 最后一块石头的重量II、LeetCode 494 目标和、LeetCode 474 一和零
LeetCode 1049 最后一块石头的重量 继续昨天没有详细说的01背包问题往下继续说。01背包问题是将dp从一维问题升维到二维之后会遇到的一类典型问题。dp数组自然而然地是一个横坐标表示物品序号-1,纵坐标表示背包重量的二维数组。01背包由一个背包是否放该物品并比照后…...

【数据结构与算法(C 语言)】栈的基本操作函数(动图演示) 及 栈的实际应用之一:进制转换
目录 1. 前言2. 结构及基本操作函数:2.1 栈的结构类型 Stack2.2 初始化栈 InitStack2.3 销毁栈 DestroyStack2.4 清空栈 ClearStack2.5 判断栈是否为空 StackEmpty2.6 获取stack的长度 StackLength2.7 获取栈顶元素 GetTop2.8 入栈 Push2.9 出栈 Pop2.10 访问元素2.…...

[原创]C++ 11的thread_local线程局部变量与Lambda表达式配合使用, 却引发致命的, 难以发现的冲突.
[简介] 常用网名: 猪头三 出生日期: 1981.XX.XX QQ联系: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、D…...

C语言-单精度和双精度浮点型
文章目录 一、遇到的问题二、解决方案三、问题根因float和double的区别: 总结-浮点数 一、遇到的问题 将NXP项目的代码移植到RH850F1K的项目上时,程序运行异常: u16Volt (uint16)((double)u16ADVal * (double)6.3) 执行到这一行程序就跑飞了…...

STM32学习问题总结(2)—CubeMX生成项目后串口没效果和Microlib
检查完所有的硬件和软件部分,最后发现,又是Keil的设置问题,啊啊啊啊 打开Keil的魔术棒,勾选Target的Use Microlib选项即可,但这并不是最佳方案 最终解决方案: 参考:http://t.csdnimg.cn/2Tjfc…...

【数据结构与算法 | 二叉树篇】二叉树的前中后序遍历(递归版本)
1. 二叉树的概念 (1). 二叉树的结构 借用了一下力扣的模板 public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) { this.val val; }TreeNode(int val, TreeNode left, TreeNode right) {this.val val;this.left left;this.righ…...

Python exp用法:深入探索指数函数的奥秘
Python exp用法:深入探索指数函数的奥秘 在Python中,exp是一个非常重要的数学函数,它属于math模块的一部分,用于计算自然数e的指数。自然数e是一个无理数,约等于2.71828,它在数学、物理和工程等领域有着广…...

[有监督学习] 8.详细图解神经网络
神经网络 一直以来,人们都认为神经网络(Neural Network,NN)是模仿生物体的神经网络设计而成的。神经网络既可以用于回归,也可以用于分类,但在实际应用中常用于分类。基于神经网络的深 度学习因在图像识别和…...

我给线程池管理框架hippo4j找bug
1 虚拟机参数不生效 hippo4j的docker启动脚本位于 docker/docker-startup.sh 。从下图可以看到 JAVA_OPT放在了jar包名 hippo4j-server.jar之后,而只有项目参数才放在jar包名之后。 实际上这里JAVA_OPT中包含虚拟机参数,而虚拟机参数要放在jar包名之前…...

win10键盘按乱了,如何恢复?
今天键盘被宝宝给按乱了,好不容易给重新调整回来,记录备忘: 1、win10的asdw和方向键互换了: 使用Fnw键来回切换,OK! 2、键盘的win键失效,例如:按winD无法显示桌面。此时…...

5.29工效学-人因工程人机交互
对于工效学这门课,一直都感觉很有意思,是一个值得再认真一点的课。可惜上课的时候效率不高,有感兴趣的东西课后也没有自行去拓展开来,前面的课我感觉还讲了比较重要的东西,但是,全忘了呢(真的对…...

头歌数据结构与算法课程设计中-硬币找零
给定n种不同面值的硬币k_i和每种硬币的数量x_i以及一个总金额k,请编写一个程序计算最少需要几枚硬币凑出这个金额k,凑出的方案是什么? 如果凑不出则输出“凑不出” 输入描述: 第一行两个正整数,n和k 然后n行每行两个数k_i和x_i 表示k_i面值的硬币有x_i个,中间以空格分隔 输…...

Golang的内存关系
1.Page Golang的Page,在操作系统对虚拟内存管理的MMU定义的物理页有相似的定义,默认的Page为8KB 2.mSpan 多个连续的Page称之为是一个Span,其定义含义有操作系统的管理的页表相似 3.Size Class Size Class: 相当于 一个等级和刻度, 比如 第二等级 就代表 一个Pag…...

VRTK4.0学习——(二)
手柄绑定以及显示 1.导入CameraRigs.UnityXRPluginFramework 和 CameraRigs.TrackedAlias 预设,将CameraRigs.UnityXRPluginFramework拖入CameraRigs.TrackedAlias的Elements中即可,运行软件后即可看到手柄了 注:如果无法看到手柄ÿ…...

体验Photoshop:无需下载,直接在浏览器编辑图片
搜索Photoshop时,映入眼帘的是PS软件下载,自学PS软件需要多长时间,学PS软件有必要报班吗...PS软件的设计功能很多,除了常见的图像处理功能外,还涉及图形、文本、视频、出版等。不管你是平面设计师,UI/UX设计…...

Codeforces Round 895 (Div. 3)(A,B,C)题解(自己VP的,没有参加这场比赛)
A. Two Vessels 题解: 这题直接计算两个杯子之间的差值,然后直接除以2倍杯子的容量直接过,没有任何难度 #include<bits/stdc.h> using namespace std;int t; int a,b,c;int main() {cin>>t;while(t--){cin>>a>>b>…...

9秒爬取庆余年2分集剧情
版本一: 要创建一个Python爬虫程序来爬取指定网站的分集剧情,我们需要使用requests库来发送HTTP请求,以及BeautifulSoup库来解析HTML内容。以下是一个简单的示例,展示了如何爬取你提供的网站的分集剧情,并将每集剧情保存到本地的.txt文件中。 首先,确保你已经安装了req…...

阿里云布置net core 项目
一、 创建镜像 给镜像添加触发器,编译的时候会触发k8s集群里的taget链接,从而更新项目 二,创建k8s集群 使用镜像创建 添加基本信息 镜像名称:镜像仓库》基本信息公网地址镜像Tag:创建镜像时的镜像版本镜像配置为:总…...

两整数之和 ---- 位运算
题目链接 题目: 分析: 题目中要求不能使用-, 考虑到我们的位运算异或^, 是无进位加法, 可以使用如果是无进位加法, 那么我们就要找到进位, 并进行计算, 进位只有1和1相加时才会产生进位1, 而0和1相加无进位, 进位为0, 那么我们就想到了&运算, 1&1 1, 0&1 0, 所…...

长城电脑压缩文件丢失了怎么办?怎么解决
在数字化时代,电脑已成为我们日常生活和工作中不可或缺的设备。长城电脑作为国内知名品牌,以其稳定可靠的性能赢得了广大用户的信赖。然而,即便是可靠的电脑,也难免会遇到一些问题。其中,压缩文件丢失无疑是一个令人头…...

论文笔记《基于深度学习模型的药物-靶标结合亲和力预测》
基于深度学习模型的药物-靶标结合亲和力预测 这是一篇二区的文章,算是一个综述,记录一下在阅读过程中遇到的问题。 文章目录 基于深度学习模型的药物-靶标结合亲和力预测前言一、蛋白质接触图谱二、为什么蛋白质图谱的准确性对DTA模型预测结果没有影响1…...

ArrayList和LinkedList对比,ArrayList使用注意事项
ArrayList和LinkedList对比,ArrayList使用注意事项 ArrayList 和 LinkedList 是 Java 中常用的两种集合类,它们在内部实现和性能上有一些重要的区别。 ArrayList: ArrayList 是基于动态数组实现的。它内部使用一个数组来存储元素,当数组空间…...

小熊家务帮day5-day7 客户管理模块1 (小程序认证,手机验证码认证,账号密码认证,修改密码,找回密码等)
客户管理模块 1.认证模块1.1 认证方式介绍1.1.1 小程序认证1.1.2 手机验证码登录1.1.3 账号密码认证 1.2 小程序认证1.2.1 小程序申请1.2.2 创建客户后端工程jzo2o-customer1.2.3 开发部署前端1.2.4 小程序认证流程1.2.4.1 customer小程序认证接口设计Controller层Service层调用…...

计算机图形学入门02:线性代数基础
1.向量(Vetors) 向量表示一个方向,还能表示长度(向量的摸)。一般使用单位向量表示方向。 向量加减:平行四边形法则、三角形法则。比卡尔坐标系描述向量,坐标直接相加。 1.1向量点乘(…...

函数:计算数组的元素和
一、计算数组的元素和 参数传递给函数时,实际上只有数组的首地址作为指针传递给了函数。 在函数定义中的int a[ ]等价于int *a。在只有地址信息的情况下,是无法知道数组里有多少个元素的,因此在计算数组中的元素和时,要加一个参…...