新手如何使用JavaSDK,轻松上手腾讯云COS?Java内调用对象存储桶

虽然不开心,但是头图不能少

COS对象存储是什么?一种存储海量文件的分布式存储服务,用户可通过网络随时存储和查看数据。

说白话,就是用来存储文件的,并且提供分布式存储,确保文件资源高可用。用户也不用自己去设计独立硬盘冗余阵列,存储内容安全且高效。

现在,一般厂商还会融合数据处理(比如:腾讯云的数据万象;免去自己后端处理的问题【比如:图片格式转换、水印等】),使用对象存储,好处多多(*≧ω≦)

虽然都说COS存储好,但是实际开发,怎么使用呢?快来看看Java开发,如何使用COS存储。

作者:Mintimate

博客:https://www.mintimate.cn

Mintimate’s Blog,只为与你分享

样例-图床

最近想搭建了一个图片交流和展示的网站,也可以理解为图床,存储大量的图片并生成缩略图方便后台管理。

本次就以图床系统的图片存储为例,对比传统存储在服务器内和存储在COS内的特点。

存储至服务器

最开始,我设置的是存储在服务器内,所以流程应该是:

单服务器结构

图片的存储,就是存储到服务器磁盘内:

代码语言:txt
复制
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进行缩略图生成(并存储在磁盘内):

代码语言:txt
复制
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

可以看到,基本解决我们使用服务器存储的痛点(就是比较贵,但是可以买资源包╮( ̄▽ ̄"")╭)。

这个也是本文的重头戏,所以分为三大点:

  • 创建存储桶:创建一个新的COS存储桶,用于项目文件(本文指图片)的存储。
  • 获取API密钥:Java在发送资源至COS存储桶时,进行鉴权。
  • Java工具包编写:后台请求处理以及Java项目如何和COS存储桶交互。

本文的思路是:用户上传的图片(MultipartFile),转Inputstream输入流,最后上传到存储桶内。使用的方法是0PUT Object,好处是上传简单,坏处是:

  • 文件大小上限5GB
  • 无法分片上传

考虑到 图床里图片普遍10MB以下,不需要分片和“大附件”,所以我没选择其他复杂上传。大家如果有需求,记得参考官方文档 嗷。

或者联系客服姐姐也不错,比如我碰到无法签名验证时,客服帮我排查问题:

客服很Nice!

现在,上机正式开始。以下操作,部分参考:对象存储-指南

创建存储桶

既然要上传到COS存储桶,肯定事先需要有一个存储桶吧,所以我们现在来创建。

首先进入COS页面,点击立即使用,选择存储桶列表,创建存储桶:

购买存储桶01
购买存储桶02

其中:

  • image-test-1302972711:存储桶的唯一标识,重要!(后续需要使用)。
  • ap-nanjing:这里我买的是南京地区的存储桶,所以所属地域是:ap-nanjing(后续需要使用)

当然,我的需求是将其作为图床,所以上传的文件应该是:公有读私有写

设置访问权限

获取API密钥

存储桶已经创建完成,现在我们需要获取API密钥,其实就是需要:

  • SecretId:密钥代号
  • SecretKey:密钥具体内容

获取方法也很简单,访问API密钥管理,添加即可(建议创建子账号):

获取API

这里就是我们需要的SecretIdSecretKey

密钥

到此,前期的准备工作就完成了。接下来就是Java工具包编写问题了。

Java工具包编写

这里编写一个工具包,工具包不需要实例化,用其静态方法进行图片上传就可以了,比如:

代码语言:txt
复制
public class TencentCOSUtil {
    public static String UploadIMG(MultipartFile imgFile, String imgName){
    }
}

添加依赖

之后,我们在业务层或者服务层就可以直接使用了。为了能连接腾讯云COS,我们需要用配套SDK(Software development kit),很简单,如果你有使用Maven骨架,只需要添加:

代码语言:txt
复制
<!--        腾讯云对象存储-->
<dependency>
    <groupId>com.qcloud</groupId>
    <artifactId>cos_api</artifactId>
    <version>5.6.54</version>
</dependency>
<dependency>
添加依赖

创建COSClient

我们需要创建一个COSClient,其中的属性需要的基本参数:

  • SecretId:密钥代号
  • SecretKey:密钥具体内容
  • region:COS存储桶所在地区

比如,这里我使用一个私有的静态方法进行COSClient创建:

代码语言:txt
复制
// 上文获得的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实例了。

上传方法

现在,我们编写一个上传方法,也就是上传到存储桶:

代码语言:txt
复制
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进行测试:

代码语言:txt
复制
// 测试
@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请求进行测试:

postman发送请求

页面成功响应,返回的结果:

postman查看响应结果

其实返回的结果,就是我们上传文件的MD5的值(这些内容应该存到数据库里……)

访问腾讯云的COS控制台,就可以看到我们刚刚上传的文件了:

虚拟文件夹
上传的图片

到此,我们的图片“变对象“就完成了,当然还有一些后续优化操作,这里介绍一下嗷。

自定义域名

我们上传的对象,默认域名访问是:

域名访问
访问成功

这样,确实可以使用,就是……有点不优雅,如何绑定自己的域名呢?其实,也很简单,进入控制台设置即可:

设置CDN

需要注意:

  • 域名需要解析CNAME地址
  • 域名的管理,需要到CDN控制台,包括:强制HTTPS等。

图片处理

图片处理,其实更多是使用数据万象的服务了,可以将图片裁切、压缩等等,甚至是图片审核(是否涉黄、涉及政治等)。比如对 刚刚上传的小鸟鉴黄:

代码实现
代码语言:txt
复制
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高级使用,预计不会安排了◡ ヽ(`Д´)ノ ┻━┻。