当项目为用户提供一个上传图片的功能的时候,为了减少图片占用本地的存储空间一般需要将图片上传到云端中,阿里云的OSS提供了该功能
1.注册阿里云账号https://oss.console.aliyun.com
根据步骤注册账号,并选择开通对象储存OSS服务
2.创建Bucket
3.配置跨域(这样java后台就能使用代码对它进行访问)
4.创建AccessKey 推荐使用子用户这样安全一点
5.JAVA后台编写代码使用OSS作为图片存储地址
5.1导入阿里云OSS的依赖包
<!--导入阿里云的oss依赖包-->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.10.2</version>
</dependency>
5.1编写一个controller用来提供图片上传的接口,并返回签名及OSS相关参数
@RestController
public class AlicloudOSSController {
//注入配置类
@Autowired
private AlicloudOSSProperties properties;
@GetMapping("/oss/sign")
public AjaxResult ossSign(){
// host的格式为 bucketname.endpoint 上传的文件的服务器的名字
String host = "https://" + properties.getBucketName() + "." + properties.getEndpoint();
// 用户上传文件时指定的前缀。 就是一个文件的名字
String dir = "zeng";
// 创建OSSClient实例。
OSS ossClient = null;
try {
//策略过期时间
long expireTime = 60;
long expireEndTime = System.currentTimeMillis() + expireTime * 1000;
Date expiration = new Date(expireEndTime);
// PostObject请求最大可支持的文件大小为5 GB,即CONTENT_LENGTH_RANGE为5*1024*1024*1024。
PolicyConditions policyConds = new PolicyConditions();
policyConds.addConditionItem(PolicyConditions.COND_CONTENT_LENGTH_RANGE, 0, 1048576000);
policyConds.addConditionItem(MatchMode.StartWith, PolicyConditions.COND_KEY, dir);
// 创建OSSClient实例。
ossClient = new OSSClientBuilder().build(properties.getEndpoint(), properties.getAccessKey(), properties.getSecretKey());
String postPolicy = ossClient.generatePostPolicy(expiration, policyConds);
byte[] binaryData = postPolicy.getBytes("utf-8");
String encodedPolicy = BinaryUtil.toBase64String(binaryData);
//签名
String postSignature = ossClient.calculatePostSignature(postPolicy);
//返回签名及OSS相关参数
Map<String, String> respMap = new LinkedHashMap<String, String>();
respMap.put("accessid", properties.getAccessKey());
respMap.put("policy", encodedPolicy);
respMap.put("signature", postSignature);
respMap.put("dir", dir);
respMap.put("host", host);
respMap.put("expire", String.valueOf(expireEndTime / 1000));
return AjaxResult.me().setResultObj(respMap);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
} finally {
if(ossClient != null){
ossClient.shutdown();
}
}
return null;
}
}
5.2将需要的参数放入到application配置文件中(方便修改,因为我使用了微服务)
file:
alicloud:
bucket-name: xxxxxx #上传空间bucket的名字
access-key: xxxxxxxxxxxxxxxxx #你的key 就是AccessKey ID
secret-key: xxxxxxxxxxxxxxxxxxxxxxx #你的秘钥 就是AccessKey secret
endpoint: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx #地域节点
5.3该配置类会在配置文件中扫描到指定的配置并将属性作为字段
@Component //交给spring管理
@ConfigurationProperties(value = "file.alicloud") //从配置文件中的value中获取到对应的字段信息
@Data
public class AlicloudOSSProperties {
private String bucketName;
private String accessKey;
private String secretKey;
private String endpoint;
}
6.前端上传图片
6.1我使用的是Element-ui的组件
<el-form-item prop="logo" label="公司Logo">
<!--<el-input type="text" v-model="employee.logo" auto-complete="off" placeholder="请输入logo!"></el-input>-->
<el-upload
class="upload-demo"
action="http://bucket的名字.地域节点名字"
:data="uploadData"
:before-upload="beforeUpload"
:on-success="handleSuccess"
:file-list="fileList"
list-type="picture">
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过500kb</div>
</el-upload>
</el-form-item>
6.2图片通过action路径上传之前需要从后台获取到签名及OSS相关参数
getUUID() {
var s = [];
var hexDigits = "0123456789abcdef";
for (var i = 0; i < 36; i++) {
s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
}
s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010
s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01
s[8] = s[13] = s[18] = s[23] = "-";
var uuid = s.join("");
return uuid;
}
async beforeUpload(){
await this.$http.get("/file/oss/sign").then(response=>{
//设置相关的参数
var resultObj = response.data.resultObj;
this.uploadData.policy = resultObj.policy;
this.uploadData.signature = resultObj.signature;
this.uploadData.ossaccessKeyId = resultObj.accessid;
//上传的文件名,使用UUID处理一下
this.uploadData.key = resultObj.dir + '/'+this.getUUID()+'_${filename}';
this.uploadData.dir = resultObj.dir;
this.uploadData.host = resultObj.host;
});
},
6.3使用一个对象接收数据
//提交到OSS的参数
uploadData: {
policy: '',
signature: '',
key: '',
ossaccessKeyId: '',
dir: '',
host: ''
}
6.4上传成功或者失败后返回的信息
handleSuccess(res, file) {
//this.fileList.pop();
//上传的完整的文件地址
var urlPath = this.uploadData.host + '/' + this.uploadData.key.replace("${filename}",file.name) ;
this.employee.logo = urlPath;
this.$message({message: '上传成功,图片地址:'+this.employee.logo, type: 'success' });
}