Spring Boot 腾讯云对象存储

本文将介绍如何在 SpringBoot 应用中集成腾讯云对象存储,将文件存储于腾讯云之中。

一、什么是对象存储?

对象存储(Cloud Object Storage,COS)是腾讯云提供的一种存储海量文件的分布式存储服务,具有高扩展性、低成本、可靠安全等优点。通过控制台、API、SDK 和工具等多样化方式,用户可简单、快速地接入 COS,进行多格式文件的上传、下载和管理,实现海量数据存储和管理。

二、准备工作

  • 创建腾讯云账号

  • 开通对象存储

  • 新建存储桶

  • 获取 secretId、secretKey、存储桶名、存储区域、访问域名等信息

    用于认证身份、存储文件、访问文件

三、集成对象存储

1. 导入依赖

在 pom.xml 中添加依赖信息如下:

1
2
3
4
5
6
<!--腾讯云cos-->
<dependency>
<groupId>com.qcloud</groupId>
<artifactId>cos_api</artifactId>
<version>5.6.61</version>
</dependency>

2. 添加配置信息

在 SpringBoot 的配置文件中,添加配置信息如下:

1
2
3
4
5
6
7
8
9
10
# 腾讯云对象存储
tencentCloud:
secretId:
secretKey:
# 存储桶名
bucket:
# 存储区域
area:
# 访问域名
url:

这里的信息是重要信息,谨防泄露!

3. 上传接口类

新建上传接口类,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
@RestController
public class UploadController {

@Value("${tencentCloud.secretId}")
private String secretId;
@Value("${tencentCloud.secretKey}")
private String secretKey;
@Value("${tencentCloud.bucket}")
private String bucket; /*存储桶名*/
@Value("${tencentCloud.area}")
private String area; /*存储区域*/
@Value("${tencentCloud.url}")
private String url; /*访问域名*/

@PostMapping("/upload")
public Object Upload(@RequestParam(value = "file") MultipartFile multipartFile) {
if (multipartFile == null || multipartFile.getOriginalFilename() == null) {
return ResultObj.failed("上传失败");
}
// 后缀名【包括.】
String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));
// 新文件名
String newFileName = System.currentTimeMillis() + suffix;
// 1 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 2 设置bucket的区域
ClientConfig clientConfig = new ClientConfig(new Region(area));
// 3 生成cos客户端
COSClient cosclient = new COSClient(cred, clientConfig);
try {
// 由MultipartFile实例生成File实例
File file = File.createTempFile("temp", null);
multipartFile.transferTo(file);
// 存储文件的唯一路径
String key = "/" + AdminUtil.getCurrentAdminId() + "/" + newFileName;
PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, key, file);
PutObjectResult putObjectResult = cosclient.putObject(putObjectRequest);
return ResultObj.successData(url + key);
} catch (IOException e) {
return ResultObj.failed("上传失败");
} finally {
// 关闭客户端(关闭后台线程)
cosclient.shutdown();
}
}
}

4. 上传接口类的优化

注意到腾讯云对象存储官方文档中有提醒如下:

COSClient 是线程安全的类,允许多线程访问同一实例。因为实例内部维持了一个连接池,创建多个实例可能导致程序资源耗尽,请确保程序生命周期内实例只有一个,并在不再需要使用时,调用 shutdown 方法将其关闭。如果需要新建实例,请先将之前的实例关闭。

因此可以对上传接口类进行修改,使 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
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@RestController
public class UploadController {

@Value("${tencentCloud.secretId}")
private String secretId;
@Value("${tencentCloud.secretKey}")
private String secretKey;
@Value("${tencentCloud.bucket}")
private String bucket; /*存储桶名*/
@Value("${tencentCloud.area}")
private String area; /*存储区域*/
@Value("${tencentCloud.url}")
private String url; /*访问域名*/

@Bean
COSClient getCosClient() {
// 1 初始化用户身份信息(secretId, secretKey)
COSCredentials cred = new BasicCOSCredentials(secretId, secretKey);
// 2 设置bucket的区域
ClientConfig clientConfig = new ClientConfig(new Region(area));
// 3 生成cos客户端
return new COSClient(cred, clientConfig);
}

@Autowired
COSClient cosClient;

@PostMapping("/upload")
public Object Upload(@RequestParam(value = "file") MultipartFile multipartFile) {
if (multipartFile == null || multipartFile.getOriginalFilename() == null) {
return ResultObj.failed("上传失败");
}
// 后缀名【包括.】
String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));
// 新文件名
String newFileName = System.currentTimeMillis() + suffix;
try {
// 由MultipartFile实例生成File实例
File file = File.createTempFile("temp", null);
multipartFile.transferTo(file);
// 拼接存储文件的唯一路径
String key = "/" + "admin" + "/" + AdminUtil.getCurrentAdminId() + "/" + newFileName;
// 上传文件
PutObjectRequest putObjectRequest = new PutObjectRequest(bucket, key, file);
PutObjectResult putObjectResult = cosClient.putObject(putObjectRequest);
return ResultObj.successData(url + key);
} catch (IOException e) {
return ResultObj.failed("上传失败");
}
}
}

参考