• SpringBoot集成腾讯COS流程


    1.pom.xml中添加cos配置

    1. <dependency>
    2. <groupId>com.qcloudgroupId>
    3. <artifactId>cos_apiartifactId>
    4. <version>5.6.28version>
    5. dependency>

    2.application.yaml中添加cos配置

    1. # 腾讯云存储cos相关公共配置
    2. tencent:
    3. cos:
    4. secretId: ABIDFG5gz36gMp2xbyHvYw3u
    5. secretKey: 93ima8OcaHhDUUDjEdmfYEd
    6. bucketName: haha-18888888
    7. folder: video
    8. region: ap-shanghai

    3.创建属性映射类CosProperties

    1. /**
    2. * Cos配置
    3. */
    4. @Data
    5. @Component
    6. @RefreshScope
    7. @ConfigurationProperties(prefix = "tencent.cos")
    8. public class CosProperties {
    9. private String secretId;
    10. private String secretKey;
    11. private String bucketName;
    12. private String folder;
    13. private String region;
    14. }

    4.封装Cos工具类

    1. /**
    2. * cos 工具类
    3. */
    4. @Slf4j
    5. public class CosUtils {
    6. private static CosUtils cosUtils = new CosUtils();
    7. private COSClient cosClient;
    8. public static CosUtils getInstance() {
    9. return cosUtils;
    10. }
    11. private CosProperties cosProperties;
    12. public CosUtils setCosProperties(CosProperties cosProperties) {
    13. this.cosProperties = cosProperties;
    14. this.cosClient = createCOSClient(cosProperties);
    15. return this;
    16. }
    17. public String getUploadTemporaryToken(String key) {
    18. if (StrUtil.hasBlank(cosProperties.getSecretId(), cosProperties.getSecretKey())) {
    19. return null;
    20. }
    21. COSCredentials cred = new BasicCOSCredentials(cosProperties.getSecretId(), cosProperties.getSecretKey());
    22. COSSigner signer = new COSSigner();
    23. // 设置过期时间为1个小时
    24. LocalDateTime now = LocalDateTime.now();
    25. Date expiredTime = new Date(now.toInstant(ZoneOffset.of("+8")).toEpochMilli() + 3600L * 1000L);
    26. // 要签名的 key, 生成的签名只能用于对应此 key 的上传
    27. log.info("待签名key[{}], now[{}]", key, now);
    28. String signStr = signer.buildAuthorizationStr(HttpMethodName.PUT, key, cred, expiredTime);
    29. log.info("签名成功, key[{}], now[{}], signStr[{}]", key, now, signStr);
    30. return signStr;
    31. }
    32. /**
    33. * 上传文件
    34. * 1.创建本地文件 2.上传
    35. *
    36. * @param fileName 文件名(带后缀)
    37. * @param fileContent 文件内容
    38. * @return
    39. */
    40. public String upload(String fileName, String fileContent, String customizeFolder) {
    41. try {
    42. String cosSecretId = cosProperties.getSecretId();
    43. String cosSecretKey = cosProperties.getSecretKey();
    44. String folder = StringUtils.isEmpty(customizeFolder) ? cosProperties.getFolder() : customizeFolder;
    45. String bucketName = cosProperties.getBucketName();
    46. if (StringUtils.isEmpty(cosSecretId) ||
    47. StringUtils.isEmpty(cosSecretKey) ||
    48. StringUtils.isEmpty(bucketName) ||
    49. StringUtils.isEmpty(folder)) {
    50. log.error("cos upload params Incomplete");
    51. return "";
    52. }
    53. String root = Objects.requireNonNull(CosUtils.class.getResource("/")).getPath();
    54. String s = root + "/temp/upload/";
    55. File localFile = getLocalFile(fileContent, s, fileName);
    56. if (localFile == null) {
    57. return "";
    58. }
    59. DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    60. String fromatDate = LocalDateTime.now().format(formatter);
    61. String fileUrl = folder + "/" + fromatDate + "/" + fileName;
    62. PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileUrl, localFile);
    63. // 设置存储类型, 默认是标准(Standard), 低频(standard_ia)
    64. putObjectRequest.setStorageClass(StorageClass.Standard);
    65. try {
    66. this.cosClient.putObject(putObjectRequest);
    67. } catch (CosClientException e) {
    68. log.error("An exception occurs during execution cos upload,error message:{}", e.getMessage());
    69. }
    70. //删除本地缓存文件
    71. if (localFile.exists()) {
    72. localFile.delete();
    73. }
    74. return fileUrl.startsWith("/") ? fileUrl : "/" + fileUrl;
    75. }catch (Exception e){
    76. log.error("文件上传失败,{}",e);
    77. }
    78. return StrUtil.EMPTY;
    79. }
    80. /**
    81. * 删除文件
    82. *
    83. * @param bucketName
    84. * @param key
    85. * @return
    86. */
    87. public Boolean deleteCosFile(String bucketName, String key) {
    88. String cosSecretId = cosProperties.getSecretId();
    89. String cosSecretKey = cosProperties.getSecretKey();
    90. Boolean executeFlag = true;
    91. if (StringUtils.isEmpty(cosSecretId) ||
    92. StringUtils.isEmpty(cosSecretKey) ||
    93. StringUtils.isEmpty(bucketName) ||
    94. StringUtils.isEmpty(key)) {
    95. log.error("cos delete file params Incomplete");
    96. return false;
    97. }
    98. COSCredentials cred = new BasicCOSCredentials(cosSecretId, cosSecretKey);
    99. // 2 设置bucket的区域, COS地域的简称请参照 https://www.qcloud.com/document/product/436/6224
    100. ClientConfig clientConfig = new ClientConfig(new Region("ap-nanjing"));
    101. // 3 生成cos客户端
    102. COSClient cosclient = new COSClient(cred, clientConfig);
    103. try {
    104. cosclient.deleteObject(bucketName, key);
    105. } catch (CosClientException e) {
    106. log.error("An exception occurs during execution cos delete,error message:{}", e.getMessage());
    107. executeFlag = false;
    108. }
    109. // 关闭客户端
    110. cosclient.shutdown();
    111. return executeFlag;
    112. }
    113. private void getDir(String path) {
    114. File localFile = new File(path);
    115. if (!localFile.exists()) {
    116. localFile.mkdirs();
    117. }
    118. }
    119. private File getLocalFile(String instructionSet, String dir, String fileName) {
    120. File localFile = null;
    121. try {
    122. getDir(dir);
    123. localFile = new File(dir, fileName);
    124. if (!localFile.exists()) {
    125. localFile.createNewFile();
    126. }
    127. FileOutputStream fos = new FileOutputStream(localFile, true);
    128. OutputStreamWriter osw = new OutputStreamWriter(fos);
    129. BufferedWriter bw = new BufferedWriter(osw);
    130. bw.write(instructionSet);
    131. bw.newLine();
    132. bw.flush();
    133. bw.close();
    134. osw.close();
    135. fos.close();
    136. return localFile;
    137. } catch (IOException e2) {
    138. log.error("An exception occurs during execution create local file,error message:{} ", e2.getMessage());
    139. return null;
    140. }
    141. }
    142. /**
    143. * 获取二进制文件
    144. */
    145. public static byte[] downLoadBinary(String urlStr) throws IOException {
    146. HttpURLConnection conn = null;
    147. InputStream inputStream = null;
    148. ByteArrayOutputStream bos = null;
    149. try {
    150. URL url = new URL(urlStr);
    151. conn = (HttpURLConnection) url.openConnection();
    152. //设置超时间为10秒
    153. conn.setConnectTimeout(10 * 1000);
    154. 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");
    155. //得到输入流
    156. inputStream = conn.getInputStream();
    157. bos = new ByteArrayOutputStream();
    158. //获取数据数组
    159. return readInputStream(inputStream, bos);
    160. } finally {
    161. if (bos != null) {
    162. bos.close();
    163. }
    164. if (inputStream != null) {
    165. inputStream.close();
    166. }
    167. if (conn != null) {
    168. conn.disconnect();
    169. }
    170. }
    171. }
    172. /**
    173. * 获取字符串列表
    174. */
    175. public static List downLoadList(String urlStr) throws IOException {
    176. HttpURLConnection conn = null;
    177. InputStream inputStream = null;
    178. try {
    179. URL url = new URL(urlStr);
    180. conn = (HttpURLConnection) url.openConnection();
    181. //设置超时间为10秒
    182. conn.setConnectTimeout(10 * 1000);
    183. 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");
    184. //得到输入流
    185. inputStream = conn.getInputStream();
    186. //获取数据数组 windows操作系统默认编码:GB18030
    187. return IoUtil.readLines(new InputStreamReader(inputStream, Charset.forName("GB18030")), new ArrayList<>());
    188. } catch (IOException e){
    189. log.error("An exception occurs during execution download file,error message:{} ", e.getMessage());
    190. return Collections.EMPTY_LIST;
    191. }finally {
    192. if (inputStream != null) {
    193. inputStream.close();
    194. }
    195. if (conn != null) {
    196. conn.disconnect();
    197. }
    198. }
    199. }
    200. /**
    201. * 输入流转二进制
    202. */
    203. public static byte[] readInputStream(InputStream inputStream, ByteArrayOutputStream bos) throws IOException {
    204. byte[] buffer = new byte[1024];
    205. int len = 0;
    206. while ((len = inputStream.read(buffer)) != -1) {
    207. bos.write(buffer, 0, len);
    208. }
    209. return bos.toByteArray();
    210. }
    211. /**
    212. * 创建cosClient
    213. *
    214. * @param cosProperties
    215. * @return
    216. */
    217. public static COSClient createCOSClient(CosProperties cosProperties) {
    218. // 1 初始化用户身份信息(secretId, secretKey)。
    219. // SECRETID和SECRETKEY请登录访问管理控制台 https://console.cloud.tencent.com/cam/capi
    220. // 进行查看和管理
    221. String secretId = cosProperties.getSecretId();
    222. String secretKey = cosProperties.getSecretKey();
    223. COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
    224. // 2 设置 bucket 的地域, COS 地域的简称请参照
    225. // https://cloud.tencent.com/document/product/436/6224
    226. // clientConfig 中包含了设置 region, https(默认 http), 超时, 代理等 set 方法, 使用可参见源码或者常见问题
    227. // Java SDK 部分。
    228. Region region = new Region(cosProperties.getRegion());
    229. ClientConfig clientConfig = new ClientConfig(region);
    230. // 这里建议设置使用 https 协议
    231. // 从 5.6.54 版本开始,默认使用了 https
    232. clientConfig.setHttpProtocol(HttpProtocol.https);
    233. // 3 生成 cos 客户端。
    234. return new COSClient(cred, clientConfig);
    235. }
    236. /**
    237. * 获取视频属性: (宽度、高度、时长)
    238. * 获取方式:从oss获取
    239. *
    240. * @param ossUrl
    241. * @return
    242. */
    243. public VideoProperties getVideoPropertiesFromCos(String ossUrl) {
    244. try {
    245. // 此处的key为对象键,对象键是对象在存储桶内的唯一标识
    246. String key = ossUrl;
    247. GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest("greatpan-1300159541", key, HttpMethodName.GET);
    248. // 设置签名过期时间(可选), 若未进行设置, 则默认使用 ClientConfig 中的签名过期时间(1小时)
    249. // 可以设置任意一个未来的时间,推荐是设置 10 分钟到 3 天的过期时间
    250. // 这里设置签名在半个小时后过期
    251. Date expirationDate = new Date(System.currentTimeMillis() + 30L * 60L * 1000L);
    252. req.setExpiration(expirationDate);
    253. req.addRequestParameter("ci-process", "videoinfo");
    254. URL url = this.cosClient.generatePresignedUrl(req);
    255. String mediaInfoXml = HttpClientUtil.doGet(url.toString());
    256. if (mediaInfoXml != null) {
    257. Document document = XmlUtil.readXML(mediaInfoXml);
    258. Node error = document.getElementsByTagName("Error").item(0);
    259. if (!ObjectUtils.isEmpty(error)) {
    260. Node message = document.getElementsByTagName("Message").item(0);
    261. log.error("获取视频基础信息出错.ossurl:{}, e:{}", ossUrl, Optional.ofNullable(message).map(Node::getTextContent).orElse(""));
    262. return null;
    263. }
    264. String width = document.getElementsByTagName("Width").item(0).getTextContent();
    265. String height = document.getElementsByTagName("Height").item(0).getTextContent();
    266. String rotation = document.getElementsByTagName("Rotation").item(0).getTextContent();
    267. if (StringUtils.isEmpty(width) || StringUtils.isEmpty(height) || StringUtils.isEmpty(rotation)) {
    268. return null;
    269. }
    270. VideoProperties videoProperties = new VideoProperties();
    271. int w = Integer.parseInt(width);
    272. int h = Integer.parseInt(height);
    273. int r = (int) Double.parseDouble(rotation);
    274. // 如果r是90或者270, 说明视频有旋转操作, 并宽高比有变化,需要把w 和 h 调换
    275. if (r % 90 == 0 && (r / 90 % 2) == 1) {
    276. videoProperties.setHeight(w);
    277. videoProperties.setWidth(h);
    278. return videoProperties;
    279. }
    280. videoProperties.setHeight(h);
    281. videoProperties.setWidth(w);
    282. return videoProperties;
    283. }
    284. return null;
    285. } catch (Exception e) {
    286. log.error("获取视频基础信息出错.ossurl:{}, e:", ossUrl, e);
    287. return null;
    288. }
    289. }
    290. public static void main(String[] args) throws Exception {
    291. // VideoProperties videoPropertiesFromCos = getVideoPropertiesFromCos("/video/2024-05-30/723d5de3-f874-4744-819f-0a31e6e8e507.mp4");
    292. // System.out.println(videoPropertiesFromCos);
    293. byte[] bytes = CosUtils.downLoadBinary("http://fs.haha.com/video/2024-05-30/1484098659191754752.txt");
    294. System.out.println(new String(bytes));
    295. }
    296. }

    5.前端获取cos上传token

    1. @Resource
    2. private CosUtils cosUtils;
    3. @GetMapping("/token")
    4. @ApiOperation("获取文件存储token")
    5. public ApiResponse getFileUploadToken(@RequestParam String fileFullPath) {
    6. if(StringUtils.isEmpty(fileFullPath)){
    7. return ApiResponse.error("参数错误");
    8. }
    9. return ApiResponse.ok(cosUtils.getUploadTemporaryToken(fileFullPath));
    10. }

  • 相关阅读:
    Ubuntu安装VM TOOLS解决虚拟机无法和WINDOWS粘贴复制问题
    【SWAT】SWAT-CUP动态基流分割相关说明
    测量工具----示波器
    Oracle 层级查询(Hierarchical Queries)
    FPmarkets:MT4中Renko图表工具有哪些?怎么用
    引擎入门 | Unity UI简介–第1部分(10)
    什么是本地存储的有效期?
    java计算机毕业设计河东街摊位管理系统源码+mysql数据库+系统+LW文档+部署
    用HTML+CSS做一个学生抗疫感动专题网页设计作业网页
    创建型:工厂模式-工厂方法、抽象工厂
  • 原文地址:https://blog.csdn.net/weixin_67727883/article/details/139319661