一、云存储技术出现的原因?
一个简单的系统中,由浏览器来上传文件到服务器,服务器接收文件后,存储到服务器本地。 如果是一个分布式系统,浏览器根据负载均衡策略可能随机到任一服务器。如果文件只保存到其中一个服务器上,其他服务器只能将文件拷贝到自己服务器上,浪费了很多资源和时间。 因此,云存储技术出现很有必要。 统一将文件存储到云端,读取文件时只需同意从云端读取即可。
二、阿里云对象存储
1、普通上传方式
普通上传方式为:用户将文件上传到服务器,服务器再将文件上传到云端。
优点是比较安全,不会泄露账号和密码。但缺点也很明显,效率低,传输所需的时间长。
2、服务端签名后直传
基于Post Policy的使用规则在服务端完成签名,然后通过表单直传数据到OSS。由于服务端签名直传无需将AccessKey暴露在前端页面,具有比较高的安全性。
三、开通阿里云对象存储服务
(1)首先得开通阿里云oss对象存储功能,并创建好一个bucket。 可参考如下链接进行开通 阿里云对象存储oss开通流程
(2)创建好bucket之后,点击右上角头像,点击AccessKey管理 (3)点击开始使用子用户AccessKey (4)点击创建用户 (5) 创建好后,添加管理对象存储服务权限
四、通过java代码在服务端完成签名
步骤1: 引入alibaba-oss依赖
<!--阿里云oss-starter-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-oss</artifactId>
<version>2.2.0.RELEASE</version>
</dependency>
步骤2: 在yml文件中添加配置
spring:
cloud:
alicloud:
secret-key: Vn2Cr6fxxxxxnzc6scOXtM23vzqzBY
access-key: LTAI5tEMxxxxCo8q9Pv3eb
oss:
endpoint: oss-cn-shanghai.aliyuncs.com
步骤3:编写配置类
@RestController
public class OssConfigController {
@Resource
private OSS ossClient;
@Value("${spring.cloud.alicloud.access-key}")
private String accessId;
@Value("${spring.cloud.alicloud.oss.endpoint}")
private String endpoint;
@RequestMapping("/oss/policy")
public Map<String, String> doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String bucket = "gulimall-beiyue";
String host = "https://"+ bucket+ "." + endpoint;
String format = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
String dir = format+ "/";
Map<String, String> respMap = null;
try {
long expireTime = 30;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
Date expiration = new Date(expireEndTime);
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes("utf-8");
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
String postSignature = ossClient.calculatePostSignature(postPolicy);
respMap = new LinkedHashMap<String, String>();
respMap.put("accessid", accessId);
respMap.put("policy", encodedPolicy);
respMap.put("signature", postSignature);
respMap.put("dir", dir);
respMap.put("host", host);
respMap.put("expire", String.valueOf(expireEndTime / 1000));
} catch (Exception e) {
System.out.println(e.getMessage());
} finally {
ossClient.shutdown();
}
return resMap;
}
}
浏览器请求“http://localhost:端口号/oss/policy”,可看到签名。
{"accessid":"LTAI5tEMdcBXXACo8q9Pv3eb",
"policy":"eyJleHBpcmF0aW9uIjoiMjAyMi0wMy0zMFQZW5ndGgtcmFuZ2UiLDAsMTA0ODU3NjAwMF0sWyJzdGFydHMtd2l0aCIsIiRrZXkiLCIyMDIyLTAzLTMwLyJdXX0=",
"signature":"7S0MZ8ZBDkK+q5ZVrWLVQq2ycRs=",
"dir":"2022-03-30/",
"host":"https://gulimall-beiyue.oss-cn-shanghai.aliyuncs.com",
"expire":"1648624790"}
将签名数据返回前端后,前端带着签名数据,直接访问host地址,就可传送图片到云端。
|