前提:

得有个腾讯云的对象存储 COS的应用,可以腾讯云购买,也可以免费使用(新开通服务提供半年的体验)。

本作者需求:将本地的图片文件上传至对象存储 COS,并将上传后文件的完整URl返回。

===================================================================

1.下面开始先创建对象存储 COS的bucket(存储桶)

2.创建存储桶基础信息

2.1、因为我获取到返回的URL后需要在网页中展示,所以选择的是公有读私有写

2.2、https://qq-test-1303*******.cos.ap-beijing.myqcloud.com,此路径是返回时拼接字符串的基础路径

3.高级设置,直接默认了,点下一步。

4.点击创建,完成存储桶的创建

5.完成后会直接跳转到创建的存储桶的文件管理页面

6.注意 我们的提取一个存储桶的地址,我选择的北京的地址,所以我的是:ap-beijing。你们要根据自己开通的地区选择。

7.我们还需要获得SecretId和SecretKey,本次因为是测试,所以使用的是最大权限的,官方是不推荐在实际项目中的运营阶段使用的,获取方法如下。

点击显示,需要手机扫码就会显示完整的信息,将信息复制保留,后面有需要

================================分割线=================================

上面的准备工作做完了,我们进入Java代码编写阶段。

一、在 maven 工程的 pom.xml 文件中添加相关依赖,内容如下:

 com.qcloud cos_api 5.6.161

查看最新maven版本(腾讯官方提供):https://mvnrepository.com/artifact/com.qcloud/cos_api

二、创建TencentCOSUtil的工具类

注意:

1.代码中的SecretId和SecretKey等我都以*替代了,你们使用时候改成自己的即可。

2.为了获取CosClient对象,在代码中我定义了一个方法getCosClient(),直接返回cosClient对象。因为这个案例中使用到了上传功能,后面还有查询,删除等别的功能都会用到这个,在后面只需要通过调用getCosClient()即可。

3.官方文件中有提到用完cosClient程序池,记得完成后通过getCosClient().shutdown()关闭。

4.通过@Component注解,将方法交给AOC容器。

package com.wanuw.utils;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.PutObjectResult;import com.qcloud.cos.region.Region;import org.springframework.stereotype.Component;import org.springframework.web.multipart.MultipartFile;import java.io.InputStream;import java.net.URL;import java.util.UUID;//交给IOC容器管理@Componentpublic class TencentCOSUtil {// COS的SecretIdprivate static String secretId = "AKID9***********************";// COS的SecretKeyprivate static String secretKey = "f5IG0************************";//文件上传后访问路径的根路径,后面要最佳文件名字与类型private static String rootSrc = "https://qq-test-1303******.cos.ap-beijing.myqcloud.com/";//上传的存储桶的地域,可参考根路径https://qq-test-1303******.cos.地域.myqcloud.com,此参数在COS的后台能查询。private static String bucketAddr = "ap-beijing";//存储桶的名字,是自己在存储空间自己创建的,我创建的名字是:qq-test-1303******private static String bucketName = "qq-test-1303******";/** * 1.调用静态方法getCosClient()就会获得COSClient实例 * 2.本方法根据永久密钥初始化 COSClient的,官方是不推荐,官方推荐使用临时密钥,是可以限制密钥使用权限,创建cred时有些区别 * * @return COSClient实例 */private static COSClient getCosClient() {// 1 初始化用户身份信息(secretId, secretKey)。COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);// 2.1 设置存储桶的地域(上文获得)Region region = new Region(bucketAddr);ClientConfig clientConfig = new ClientConfig(region);// 2.2 使用https协议传输clientConfig.setHttpProtocol(HttpProtocol.https);// 3 生成 cos 客户端。COSClient cosClient = new COSClient(cred, clientConfig);// 返回COS客户端return cosClient;}/** * 只要调用静态方法upLoadFile(MultipartFile multipartFile)就可以获取上传后文件的全路径 * * @param file * @return 返回文件的浏览全路径 */public static String upLoadFile(MultipartFile file) {try {// 获取上传的文件的输入流InputStream inputStream = file.getInputStream();// 避免文件覆盖,获取文件的原始名称,如123.jpg,然后通过截取获得文件的后缀,也就是文件的类型String originalFilename = file.getOriginalFilename();//获取文件的类型String fileType = originalFilename.substring(originalFilename.lastIndexOf("."));//使用UUID工具创建唯一名称,放置文件重名被覆盖,在拼接上上命令获取的文件类型String fileName = UUID.randomUUID().toString() + fileType;// 指定文件上传到 COS 上的路径,即对象键。最终文件会传到存储桶名字中的images文件夹下的fileName名字String key = "images/" + fileName;// 创建上传Object的MetadataObjectMetadata objectMetadata = new ObjectMetadata();// - 使用输入流存储,需要设置请求长度objectMetadata.setContentLength(inputStream.available());// - 设置缓存objectMetadata.setCacheControl("no-cache");// - 设置Content-TypeobjectMetadata.setContentType(fileType);//上传文件PutObjectResult putResult = getCosClient().putObject(bucketName, key, inputStream, objectMetadata);// 创建文件的网络访问路径String url = rootSrc + key;//关闭 cosClient,并释放 HTTP 连接的后台管理线程getCosClient().shutdown();return url;} catch (Exception e) {e.printStackTrace();// 发生IO异常、COS连接异常等,返回空return null;}}}

三、调试,我是使用apifox工具进行的调试。

3.1、我这面现有的需求(请求路径:/upload,请求方式:post,参数名称:image),需要返回上传后文件的url地址,大家看一下就行,仅做演示。试试返回和功能你们需要根据自己的需求去开发。虽然这个需求的参数名称是image(前端上传选择时候做了限制),不过上面的工具可以上传任意类型的数据。

package com.wanuw.controller;import com.wanuw.pojo.Result;import com.wanuw.utils.TencentCOSUtil;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.multipart.MultipartFile;@Slf4j@RestControllerpublic class UploadController {//依赖注入@Autowiredprivate TencentCOSUtil tencentCOSUtil;@PostMapping("/upload")public Result upload(MultipartFile image) {log.info("正在上传,文件名{}",image.getOriginalFilename());String url = tencentCOSUtil.upLoadFile(image);log.info("文件的Url:{}",url);return Result.success(url);}}

3.2、运行后使用apifox测试返回数据,上传成功,也返回来正确的url。

3.3、存储桶中的文件也正常显示,文件名都一致!

=================================分割线=================================

若是还有不明白的,可以关注腾讯云的官方指导手册。

由于本人刚学习Java,有些术语,名字可能会说的不准确。希望批评指正。