当前位置:   article > 正文

SpringBoot集成腾讯COS流程

SpringBoot集成腾讯COS流程

1.pom.xml中添加cos配置

  1. <!--腾讯cos -->
  2. <dependency>
  3. <groupId>com.qcloud</groupId>
  4. <artifactId>cos_api</artifactId>
  5. <version>5.6.28</version>
  6. </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<String> 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. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/659607
推荐阅读
相关标签
  

闽ICP备14008679号