COS对象存储是什么?一种存储海量文件的分布式存储服务,用户可通过网络随时存储和查看数据。
说白话,就是用来存储文件的,并且提供分布式存储,确保文件资源高可用。用户也不用自己去设计独立硬盘冗余阵列,存储内容安全且高效。
现在,一般厂商还会融合数据处理(比如:腾讯云的数据万象;免去自己后端处理的问题【比如:图片格式转换、水印等】),使用对象存储,好处多多(*≧ω≦)
虽然都说COS存储好,但是实际开发,怎么使用呢?快来看看Java开发,如何使用COS存储。
作者:Mintimate
博客:https://www.mintimate.cn
Mintimate’s Blog,只为与你分享
样例-图床
最近想搭建了一个图片交流和展示的网站,也可以理解为图床,存储大量的图片并生成缩略图方便后台管理。
本次就以图床系统的图片存储为例,对比传统存储在服务器内和存储在COS内的特点。
存储至服务器
最开始,我设置的是存储在服务器内,所以流程应该是:
图片的存储,就是存储到服务器磁盘内:
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进行缩略图生成(并存储在磁盘内):
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,好处是上传简单,坏处是:
- 文件大小上限5GB
- 无法分片上传
考虑到 图床里图片普遍10MB以下,不需要分片和“大附件”,所以我没选择其他复杂上传。大家如果有需求,记得参考官方文档 嗷。
或者联系客服姐姐也不错,比如我碰到无法签名验证时,客服帮我排查问题:
现在,上机正式开始。以下操作,部分参考:对象存储-指南
创建存储桶
既然要上传到COS存储桶,肯定事先需要有一个存储桶吧,所以我们现在来创建。
首先进入COS页面,点击立即使用,选择存储桶列表,创建存储桶:
其中:
image-test-1302972711
:存储桶的唯一标识,重要!(后续需要使用)。ap-nanjing
:这里我买的是南京地区的存储桶,所以所属地域是:ap-nanjing(后续需要使用)
当然,我的需求是将其作为图床,所以上传的文件应该是:公有读私有写:
获取API密钥
存储桶已经创建完成,现在我们需要获取API密钥,其实就是需要:
- SecretId:密钥代号
- SecretKey:密钥具体内容
获取方法也很简单,访问API密钥管理,添加即可(建议创建子账号):
这里就是我们需要的SecretId
和SecretKey
:
到此,前期的准备工作就完成了。接下来就是Java工具包编写问题了。
Java工具包编写
这里编写一个工具包,工具包不需要实例化,用其静态方法进行图片上传就可以了,比如:
public class TencentCOSUtil {
public static String UploadIMG(MultipartFile imgFile, String imgName){
}
}
添加依赖
之后,我们在业务层或者服务层就可以直接使用了。为了能连接腾讯云COS,我们需要用配套SDK(Software development kit),很简单,如果你有使用Maven骨架,只需要添加:
<!-- 腾讯云对象存储-->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.54</version>
</dependency>
<dependency>
创建COSClient
我们需要创建一个COSClient,其中的属性需要的基本参数:
- SecretId:密钥代号
- SecretKey:密钥具体内容
- region:COS存储桶所在地区
比如,这里我使用一个私有的静态方法进行COSClient创建:
// 上文获得的SecretId private static String secretId = "AKIDH************************UFv9cao"; // 上文获得的SecretKey private static String secretKey = "wdp************************fKvLV";
private static COSClient getCosClient(){
// 1 初始化用户身份信息(secretId, secretKey)。
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 2.1 设置存储桶的地域(上文获得)
Region region = new Region("ap-nanjing");
ClientConfig clientConfig = new ClientConfig(region);
// 2.2 使用https协议传输
clientConfig.setHttpProtocol(HttpProtocol.https);
// 3 生成 cos 客户端。
COSClient cosClient = new COSClient(cred, clientConfig);
// 返回COS客户端
return cosClient;
}
需要注意,这里的存储桶地域就是上文创建存储桶所设置的,如果你不知道填什么,可以到控制台内查看:
这样调取getCosClient()
方法就会获得COSClient实例了。
上传方法
现在,我们编写一个上传方法,也就是上传到存储桶:
public static String UploadIMG(MultipartFile imgFile, String imgName) {
try {
InputStream inputStream = imgFile.getInputStream();
// 创建上传Object的Metadata
ObjectMetadata objectMetadata = new ObjectMetadata();
// - 使用输入流存储,需要设置请求长度
objectMetadata.setContentLength(inputStream.available());
// - 设置缓存
objectMetadata.setCacheControl("no-cache");
// - 设置Content-Type
objectMetadata.setContentType(getcontentType(imgName.substring(imgNam.lastIndexOf("."))));
// 指定文件将要存放的存储桶
String bucketName = "image-test-1302972711";
// 指定文件上传到 COS 上的路径,即对象键。
String key = "imageHost/" + imgName;
PutObjectResult putResult = getCosClient().putObject(bucketName, key,inputStream, objectMetadata);
// 成功存储后,返回图片MD5
return putResult.getContentMd5();
} catch (Exception e) {
e.printStackTrace();
// 发生IO异常、COS连接异常等,返回空
return null;
}
}
这里我采用输入流并重命名文件的方式,进行上传。需要注意:
- 对象键:其实就是虚拟目录了,这里
imageHost/
开头,就是在存储桶的根目录下,创建一个imageHost文件夹。若后面接着文件名,顾名思义,就是创建imageHost文件夹后,并将文件放入其内。
我们编辑一个Controller进行测试:
// 测试
@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等。
图片处理
图片处理,其实更多是使用数据万象的服务了,可以将图片裁切、压缩等等,甚至是图片审核(是否涉黄、涉及政治等)。比如对 刚刚上传的小鸟鉴黄:
public static String judgeIMG() {
//1.创建任务请求对象
ImageAuditingRequest request = new ImageAuditingRequest();
//2.添加请求参数 参数详情请见api接口文档
//2.1设置请求bucket
request.setBucketName("image-test-1302972711");
//2.2设置审核类型
request.setDetectType("porn");
//2.3设置bucket中的图片位置
request.setObjectKey("imageHost/动物-鸟.jpg");
//3.调用接口,获取任务响应对象
ImageAuditingResponse response = getCosClient().imageAuditing(request);
return response.getPornInfo().getHitFlag();
}
返回结果为0,也就是图片不涉黄。
可以看到,用腾讯云的 Java SDK处理还是很方便的。但是我发现图片标签识别等,还没有配套SDK方法,希望腾讯云 后期可以补上,不然……自己写Http请求,挺麻烦的。
END
嘿嘿,有多少人看到最后了呢?
其实,使用COS很简单,如果你以前觉得COS存储很麻烦,或者认为项目小,而没有使用COS…… 还是建议尝试。并且真正用了COS,感觉也不麻烦,甚至还很方便。
并且文件资源更加安全了,实在出现不可读取情况,还可以甩锅给腾讯╮( ̄▽ ̄"")╭,避免自己被打~~比存储在我们自己服务器好多了。
大家对此感兴趣,强烈建议试试嗷。不过大型项目,记得购买资源包哟。
本教程和图文,腾讯云存储平台评估为三等奖,如果你需要更专业,“建议”看看他们评估的一等奖、二等奖。后续COS高级使用,预计不会安排了◡ ヽ(`Д´)ノ ┻━┻。