OSS对象存储
Posted YuanChuZiWen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OSS对象存储相关的知识,希望对你有一定的参考价值。
OSS对象存储
当项目以微服务搭建时,多个服务往往运行在多台服务器上,此时针对存储文件的获取和保存,难以确定具体的位置;
针对这个问题,一般有两个办法:
- 搭建独立的文件存储服务器,用 FastDFS等构建
- 使用第三方的对象存储 OSS,如 阿里云的 OSS
一、数据库的设计
一般数据库设计字段存储文件在上传 OSS后返回的地址值,字段宜采用 Varchar
二、后端
一般有两种用法:
- 前端把待传文件,先传给服务器,然后服务器传给阿里云
- 前端向服务器索取验证用的 Access Key等校验信息,然后独立传给 阿里云,最后再把结果传给服务器
一般使用后者
2.1、依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alicloud-oss</artifactId>
</dependency>
该依赖中包含了原始的 aliyun-sdk-oss
,并且强制在配置文件中配置对象存储的信息,并且会自动创建 OSSclient
对象
2.2、配置
spring:
cloud:
alicloud:
access-key: LTAI5tKV72y86Xty********
secret-key: BJXWfm4lxgc9Wv2LA2Z**********
oss:
endpoint: oss-cn-hangzhou.aliyuncs.com
bucket: oliq-gulimall #这个不是默认的配置,这么写是为了方便代码里面通过 @Value()获取
2.3、使用
package com.zwb.gulimall.thirdparty.controller;
import com.aliyun.oss.OSSClient;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.aliyun.oss.model.MatchMode;
import com.aliyun.oss.model.PolicyConditions;
import com.zwb.common.utils.R;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
/**
* @author:OliQ
* @date: Created on 2022-01-20 16:40
* @description:
*/
@RestController()
@RequestMapping("/oss")
public class OSSController
@Resource
private OSSClient ossClient;
@Value("$spring.cloud.alicloud.oss.bucket")
private String bucket;
@Value("$spring.cloud.alicloud.oss.endpoint")
private String endpoint;
@Value("$spring.cloud.alicloud.access-key")
private String accessId;
@RequestMapping("/policy")
public R policy()
String host = "https://" + bucket + "." + endpoint; // host的格式为 bucketname.endpoint
// callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
// String callbackUrl = "http://88.88.88.88:8888";
String dir = LocalDate.now().toString(); // 用户上传文件时指定的前缀。
Map<String, String> respMap = null;
try
long expireTime = 30;
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);
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));
// respMap.put("expire", formatISO8601Date(expiration));
catch (Exception e)
// Assert.fail(e.getMessage());
System.out.println(e.getMessage());
finally
ossClient.shutdown();
return R.ok().put("data", respMap);
三、前端
主要逻辑就是:
- 向服务器发请求获取 验证信息
- 向阿里云上传数据
- 将文件路径交给服务器
3.1、页面组件
<template>
<div>
<!-- action必选参数,上传地址,bucket的外网访问域名 -->
<el-upload
action="https://oliq-gulimall.oss-cn-hangzhou.aliyuncs.com"
:data="dataObj"
list-type="picture"
:multiple="false"
:show-file-list="showFileList"
:file-list="fileList"
:before-upload="beforeUpload"
:on-remove="handleRemove"
:on-success="handleUploadSuccess"
:on-preview="handlePreview"
>
<el-button size="small" type="primary">点击上传</el-button>
<div slot="tip" class="el-upload__tip">
只能上传jpg/png文件,且不超过10MB
</div>
</el-upload>
<el-dialog :visible.sync="dialogVisible">
<img :src="fileList[0].url" />
</el-dialog>
</div>
</template>
3.2、数据
data()
return
dataObj:
policy: "",
signature: "",
key: "",
ossaccessKeyId: "",
dir: "",
host: "",
// callback:\'\',
,
dialogVisible: false,
;
,
3.3、JS
methods:
emitInput(val)
this.$emit("input", val);
,
handleRemove(file, fileList)
this.emitInput("");
,
handlePreview(file)
this.dialogVisible = true;
,
beforeUpload(file)
let _self = this;
return new Promise((resolve, reject) =>
policy()
.then((response) =>
_self.dataObj.policy = response.data.policy;
_self.dataObj.signature = response.data.signature;
_self.dataObj.ossaccessKeyId = response.data.accessid;
_self.dataObj.key =
response.data.dir + "/" + getUUID() + "_$filename";
_self.dataObj.dir = response.data.dir;
_self.dataObj.host = response.data.host;
console.log("上传前请求服务端签名,得到结果:", _self.dataObj);
resolve(true);
)
.catch((err) =>
reject(false);
);
);
,
handleUploadSuccess(res, file)
console.log("上传成功...");
this.showFileList = true;
this.fileList.pop();
this.fileList.push(
name: file.name,
url:
this.dataObj.host +
"/" +
this.dataObj.key.replace("$filename", file.name),
);
this.emitInput(this.fileList[0].url);
,
,
请求发送代码:
import http from \'@/utils/httpRequest.js\'
export function policy()
return new Promise((resolve,reject)=>
http(
url: http.adornUrl("/thirdparty/oss/policy"),
method: "get",
params: http.adornParams()
).then(( data ) =>
resolve(data);
).catch(err =>
console.log("出错了...",err)
reject(false);
);
);
以上是关于OSS对象存储的主要内容,如果未能解决你的问题,请参考以下文章