本文最后更新于 2024年1月6日 下午
COS对象存储是什么?对象存储COS(英文Cloud Object Storage)是腾讯云提供的一种存储海量文件的分布式存储服务,用户可通过网络随时存储和查看数据。
说白话,就是用来存储文件的,并且提供分布式存储,确保文件资源高可用。
虽然都说COS存储好,但是实际开发,怎么使用呢?快来看看Java开发,如何使用COS存储。
本教程和图文,腾讯云存储平台评估为三等奖,如果你需要更专业,建议看看他们评估的一等奖
虽然我感觉他们一等奖、二等奖专业性都不高,不清楚他们 怎么评定的:-)
高级腾讯云COS使用,不会安排了,安排也不用腾讯云COS◡ ヽ(`Д´)ノ ┻━┻
样例-图床
最近想搭建了一个图片交流和展示的网站,也可以理解为图床,存储大量的图片并生成缩略图方便后台管理。
本次就以图床系统的图片存储为例,对比传统存储在服务器内和存储在COS内的特点。
存储至服务器
最开始,我设置的是存储在服务器内,所以流程应该是:
图片的存储,就是存储到服务器磁盘内:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| private boolean saveOriginal(String originalImage, MultipartFile imageFile) { File originalImageFile = new File(originalImage); if (!originalImageFile.getParentFile().exists()) { originalImageFile.getParentFile().mkdirs(); } try { imageFile.transferTo(originalImageFile); } catch (Exception e) { e.printStackTrace(); return false; } return true; }
|
同时使用Google thumbnailator进行缩略图生成(并存储在磁盘内):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| private boolean saveThumbnail(String originalImage, String imageThumbnailPath) { File thumbnailImageFile = new File(imageThumbnailPath); if (!thumbnailImageFile.getParentFile().exists()) { thumbnailImageFile.getParentFile().mkdirs(); } try { Thumbnails.of(originalImage) .imageType(ThumbnailParameter.DEFAULT_IMAGE_TYPE) .scale(1.0f) .outputQuality(0.35f) .outputFormat("webp") .toFile(imageThumbnailPath); return true; } catch (IOException e) { e.printStackTrace(); } return false; }
|
这样的效果也很不错:
但是,我使用的是腾讯云轻量应用服务器,会有这样有三个问题(使用CVM其实也差不多):
- 单一服务器存储,服务器集群负载时候,如果服务器宕机,则图床无法使用。
- 服务器空间有限,迁移数据复杂。
- 服务器带宽有限,高并发读取图片,带宽肯定不够。
所以,还是引入COS比较好。
存储至COS
为了解决上诉问题,我使用腾讯云的COS存储桶,进行图片存储,后续项目流程结构:
可以看到,基本解决我们使用服务器存储的痛点(就是比较贵,但是可以买资源包╮( ̄▽ ̄””)╭)。
这个也是本文的重头戏,所以分为三大点:
- 创建存储桶:创建一个新的COS存储桶,用于项目文件(本文指图片)的存储。
- 获取API密钥:Java在发送资源至COS存储桶时,进行鉴权。
- Java工具包编写:后台请求处理以及Java项目如何和COS存储桶交互。
本文的思路是:用户上传的图片(MultipartFile),转Inputstream输入流,最后上传到存储桶内。使用的方法是0PUT Object,好处是上传简单,坏处是:
考虑到 图床里图片普遍10MB以下,不需要分片和“大附件”,所以我没选择其他复杂上传。大家如果有需求,记得参考官方文档 嗷。
或者联系客服姐姐也不错,比如我碰到无法签名验证时,客服帮我排查问题:
现在,上机正式开始。以下操作,部分参考:对象存储-指南
创建存储桶
既然要上传到COS存储桶,肯定事先需要有一个存储桶吧,所以我们现在来创建。
首先进入COS页面,点击立即使用,选择存储桶列表,创建存储桶:
其中:
image-test-1302972711
:存储桶的唯一标识,重要!(后续需要使用)。
ap-nanjing
:这里我买的是南京地区的存储桶,所以所属地域是:ap-nanjing(后续需要使用)
当然,我的需求是将其作为图床,所以上传的文件应该是:公有读私有写:
获取API密钥
存储桶已经创建完成,现在我们需要获取API密钥,其实就是需要:
- SecretId:密钥代号
- SecretKey:密钥具体内容
获取方法也很简单,访问API密钥管理,添加即可(建议创建子账号):
这里就是我们需要的SecretId
和SecretKey
:
到此,前期的准备工作就完成了。接下来就是Java工具包编写问题了。
Java工具包编写
这里编写一个工具包,工具包不需要实例化,用其静态方法进行图片上传就可以了,比如:
1 2 3 4
| public class TencentCOSUtil { public static String UploadIMG(MultipartFile imgFile, String imgName){ } }
|
添加依赖
之后,我们在业务层或者服务层就可以直接使用了。为了能连接腾讯云COS,我们需要用配套SDK(Software development kit),很简单,如果你有使用Maven骨架,只需要添加:
1 2 3 4 5 6 7
| <dependency> <groupId>com.qcloud</groupId> <artifactId>cos_api</artifactId> <version>5.6.54</version> </dependency> <dependency>
|
创建COSClient
我们需要创建一个COSClient,其中的属性需要的基本参数:
- SecretId:密钥代号
- SecretKey:密钥具体内容
- region:COS存储桶所在地区
比如,这里我使用一个私有的静态方法进行COSClient创建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| private static String secretId = "AKIDH************************UFv9cao";
private static String secretKey = "wdp************************fKvLV";
private static COSClient getCosClient(){ COSCredentials cred = new BasicCOSCredentials(secretId, secretKey); Region region = new Region("ap-nanjing"); ClientConfig clientConfig = new ClientConfig(region); clientConfig.setHttpProtocol(HttpProtocol.https); COSClient cosClient = new COSClient(cred, clientConfig); return cosClient; }
|
需要注意,这里的存储桶地域就是上文创建存储桶所设置的,如果你不知道填什么,可以到控制台内查看:
这样调取getCosClient()
方法就会获得COSClient实例了。
上传方法
现在,我们编写一个上传方法,也就是上传到存储桶:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public static String UploadIMG(MultipartFile imgFile, String imgName) { try { InputStream inputStream = imgFile.getInputStream(); ObjectMetadata objectMetadata = new ObjectMetadata(); objectMetadata.setContentLength(inputStream.available()); objectMetadata.setCacheControl("no-cache"); objectMetadata.setContentType(getcontentType(imgName.substring(imgNam.lastIndexOf(".")))); String bucketName = "image-test-1302972711"; String key = "imageHost/" + imgName; PutObjectResult putResult = getCosClient().putObject(bucketName, key,inputStream, objectMetadata); return putResult.getContentMd5(); } catch (Exception e) { e.printStackTrace(); return null; } }
|
这里我采用输入流并重命名文件的方式,进行上传。需要注意:
- 对象键:其实就是虚拟目录了,这里
imageHost/
开头,就是在存储桶的根目录下,创建一个imageHost文件夹。若后面接着文件名,顾名思义,就是创建imageHost文件夹后,并将文件放入其内。
我们编辑一个Controller进行测试:
1 2 3 4 5 6 7 8 9 10
| @PostMapping( value = "/img/test", produces = { "application/json;charset=UTF-8" } ) public ResponseEntity test(@RequestParam(value = "IMG_Raw") MultipartFile IMG_Raw, @RequestParam(value = "IMG_Name") String IMG_Name){ return ResponseEntity.ok("返回值为:"+TencentCOSUtil.UploadIMG(IMG_Raw,IMG_Name));
}
|
使用Postman发送Post请求进行测试:
页面成功响应,返回的结果:
其实返回的结果,就是我们上传文件的MD5的值(这些内容应该存到数据库里……)
访问腾讯云的COS控制台,就可以看到我们刚刚上传的文件了:
到此,我们的图片“变对象“就完成了,当然还有一些后续优化操作,这里介绍一下嗷。
自定义域名
我们上传的对象,默认域名访问是:
这样,确实可以使用,就是……有点不优雅,如何绑定自己的域名呢?其实,也很简单,进入控制台设置即可:
需要注意:
- 域名需要解析CNAME地址
- 域名的管理,需要到CDN控制台,包括:强制HTTPS等。
图片处理
图片处理,其实更多是使用数据万象的服务了,可以将图片裁切、压缩等等,甚至是图片审核(是否涉黄、涉及政治等)。比如对 刚刚上传的小鸟鉴黄:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static String judgeIMG() { ImageAuditingRequest request = new ImageAuditingRequest(); request.setBucketName("image-test-1302972711"); request.setDetectType("porn"); request.setObjectKey("imageHost/动物-鸟.jpg"); ImageAuditingResponse response = getCosClient().imageAuditing(request); return response.getPornInfo().getHitFlag(); }
|
返回结果为0,也就是图片不涉黄。
可以看到,用腾讯云的 Java SDK处理还是很方便的。但是我发现图片标签识别等,还没有配套SDK方法,希望腾讯云 后期可以补上,不然……自己写Http请求,挺麻烦的。
END
嘿嘿,有多少人看到最后了呢?
其实,使用COS很简单,如果你以前觉得COS存储很麻烦,或者认为项目小,而没有使用COS…… 还是建议尝试。并且真正用了COS,感觉也不麻烦,甚至还很方便。
并且文件资源更加安全了,实在出现不可读取情况,还可以甩锅给腾讯╮( ̄▽ ̄””)╭,避免自己被打~~比存储在我们自己服务器好多了。
大家对此感兴趣,强烈建议试试嗷。不过大型项目,记得购买资源包哟。
推荐腾讯云COS嗷 。COS都差不多,用千牛、阿里都差不多。