七牛云是国内知名的云计算及数据服务提供商,持续在海量文件存储CDN内容分发、视频点播、互动直播及大规模异构数据的智能分析与处理等领域的核心技术进行深度投入,致力于以数据科技全面驱动数字化未来,赋能各行各业全面进入数据时代。

​ 我们在做一些项目时,难免会遇到需要使用文件上传的场景,例如用户上传自定义头像等。今天来讲下如何把文件上传至七牛云的对象存储COS,然后我们数据库中仅存储该文件在对象存储空间中的URL即可。

准备

  • 七牛云账号 *1

创建云存储空间

创建存储空间

登录七牛云,进入控制台,点击对象存储,然后点击新建空间

image-20200727214927893

输入要创建的存储空间名,选择存储区域和访问权限。

image-20200727215241027

创建完成后就可以看到七牛云为我分配了一个测试域名,这样我们就可以使用这个域名进行上传/下载文件了。

image-20200727220007238

⚠️ 需要注意的是:测试域名只能使用30天!!并且测试域名只能使用HTTP协议,不支持HTTPS协议

有域名的小伙伴可以在域名管理处绑定自己的域名,这样就没有测试域名的30天使用限制了,如果已经购买了并部署了ssl证书的话,还可以使用Https协议进行加密传输。

image-20200727215553196

好了,到了这一步云存储空间的创建就基本完成了,接下来我们使用Java代码在后台将文件上传至七牛云。

Java后端上传文件至七牛云

七牛云的开发者中心提供了很多版本的SDK,例如Go,JavaScript,PHP,Python,Node.js,Ruby,C#,C/C++等等,这里是我使用的是Java的SDK,写一个demo演示下如何上传文件至七牛云。

创建项目

这里我们创建一个SpringBoot项目,勾选Spring Web依赖,然后引入七牛云的SDK的依赖。

Gradle

1
compile 'com.qiniu:qiniu-java-sdk:7.2.28'

Maven

1
2
3
4
5
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.2.28</version>
</dependency>

创建七牛云的配置类

创建一个七牛云的配置类,需要用到三个属性accessKey,secretKey,bucket。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@ConfigurationProperties(prefix = "qiniucloud")
@Component
@Data
public class QiNiuCloudProperties {
/**
* AK码
*/
private String accessKey;
/**
* SK码
*/
private String secretKey;
/**
* 桶空间名
*/
private String bucket;
}

然后在application.properties文件中配置七牛云

bucket的值就是存储空间的名称,accessKey和secretKey可以将鼠标悬浮在右上角的头像上然后点击密钥管理

image-20200727224017638

然后分别复制粘贴到application.properties对应的位置处即可

image-20200727224313498

最终的配置结果如下图所示

1
2
3
4
5
6
7
#七牛云配置
qiniucloud.accessKey=yxRwIuNHcCkNFg7IvWJs_7PjORqTDWT80jLw3Szj
qiniucloud.secretKey=9BiFTNbLJ5YfF-b-3UVcr6AWFAvRvQ-1AC4ETLAw
qiniucloud.bucket=blog-mashimaro

#开启文件上传功能
spring.servlet.multipart.enabled=true

创建上传的工具类

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
@Slf4j
public class QiNiuUploadUtils {
/**
* 实现上传文件至七牛云
* @param qiNiuCloudProperties 七牛云配置类
* @param file 上传文件对象
* @return 七牛云存储的路径
*
*/
public static String upload(QiNiuCloudProperties qiNiuCloudProperties, MultipartFile file) {
// 构造一个带指定 Region 对象的配置类
Configuration configuration = new Configuration(Region.huanan());
// 七牛文件上传管理器
UploadManager uploadManager = new UploadManager(configuration);
// 获取Auth对象
Auth auth = Auth.create(qiNiuCloudProperties.getAccessKey(),qiNiuCloudProperties.getSecretKey());
// 生成上传凭证,然后准备上传
String uploadToken = auth.uploadToken(qiNiuCloudProperties.getBucket());
log.debug("生成的上传凭证是: "+uploadToken);
try {
// 上传文件 默认不指定key的情况下,以文件内容的hash值作为文件名
Response response = uploadManager.put(file.getInputStream(), null, uploadToken, null, null);
// 解析上传成功的结果
DefaultPutRet defaultPutRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
// 返回文件名
return defaultPutRet.hash;
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
return "上传失败";
} catch (IOException e) {
e.printStackTrace();
return "上传失败";
}

}
}

创建Controller类

编写文件上传的Controller类,并编写上传的接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RestController
public class QiNiuUploadController {

@Autowired
private QiNiuCloudProperties qiNiuCloudProperties;

@PostMapping("/upload")
public String upload(@RequestParam("file") MultipartFile file){
// 存储空间的域名
String domain = "http://qe4svkefq.bkt.clouddn.com/";
// 返回文件在七牛云对象存储空间中的url
return domain+QiNiuUploadUtils.upload(qiNiuCloudProperties, file);
}
}

创建前端上传页面

1
2
3
4
5
6
7
8
9
10
11
12
13
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/upload" method="post" enctype="multipart/form-data">
文件上传:<input type="file" name="file"><br/>
<input type="submit" value="上传">
</form>
</body>
</html>

⚠️ 表单的enctype属性需要设置为multipart/form-data

否则会报错: Current request is not a multipart request

运行demo

打开浏览器输入http://localhost:8080/后回车,然后选择一个文件,这里我选择一张壁纸。

image-20200727225510705

点击上传后服务器为我们返回了一个url,我们复制到浏览器打开

image-20200727225920069

可以看到,已经能够访问到我们上传的图片了。

image-20200727230017528

结语

相比把文件全部上传到我们服务器上来说,使用对象存储来保存我们的资源的方式帮助我们大幅减轻了服务器的IO压力,并且提高了容灾能力。最重要的是便宜,比如阿里云对象存储40G容量一年的价格大概是9块钱,七牛云提供免费的10G存储空间等。所以,我们有什么理由不使用该项技术呢?