Spring Boot+Vue项目整合七牛云OSS对象存储,实现文件上传下载和删除
一、介绍七牛云对象存储 Kodo 是七牛云提供的高可靠、强安全、低成本、可扩展的存储服务。您可通过控制台、API、SDK 等方式简单快速地接入七牛存储服务,实现海量数据的存储和管理。通过 Kodo 可以进行文件的上传、下载和管理。七牛云对象存储提供高可用和高可靠的对象存储服务,您可以放心的将各种内容存储在云端。利用七牛云对象存储的扩展性和按需付费的优势,可以满足您持续快速增长的存储需求。您...
一、介绍
七牛云对象存储 Kodo 是七牛云提供的高可靠、强安全、低成本、可扩展的存储服务。您可通过控制台、API、SDK 等方式简单快速地接入七牛存储服务,实现海量数据的存储和管理。通过 Kodo 可以进行文件的上传、下载和管理。
七牛云对象存储提供高可用和高可靠的对象存储服务,您可以放心的将各种内容存储在云端。利用七牛云对象存储的扩展性和按需付费的优势,可以满足您持续快速增长的存储需求。您也可以搭配使用七牛云的对象存储和融合 CDN服务,实现全球覆盖、快速高效的内容分发。
二、实现步骤
1、准备工作
首先到七牛云注册并登录账号,这里就不介绍注册登录步骤了,注册登录完后进入管理控制台首页,在七牛云官方产品中添加对象存储,如下图
a、弹出侧边添加按钮,我们按要求填写存储空间名称,如:linfen-test,
b、看你自己区域进行选择存储区域,如:华东,
c、再接着选择公开或私有访问,公开对文件访问可以直接:空间域名加存储文件名就可以直接访问下载,私有的话再访问文件时需要携带token和有效时间戳进行访问才能下载文件
创建好bucket存储空间后我们去获取密钥,点击头像去个人中心>选择密钥管理,复制AK和SK这两个密钥后面要用到
2.后端进行项目整合
2.1添加项目依赖
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>7.2.28</version>
</dependency>
2.2配置application.yml文件
#七牛云配置
qiniu:
accessKey: 0CQcXKb0Mjti_WrxZfsdGgmkdngsdYyfffka1dGq
secretKey: fWGdsfkaoDGspGeeSGvEgVR9JYDFdsjiadddxx9V
bucketName: linfen-test
fileDomain: q7omvujlt.bkt.clouddn.com #文件访问域名前缀(可配置自己的域名)
文件访问前缀,可以到空间管理>空间概览>CDN 测试域名的最下面就是默认配置的域名
2.3创建上传工具类QiniuUtil.java
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Client;
import com.qiniu.http.Response;
import com.qiniu.storage.BucketManager;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
/**
* 七牛云工具类
*@author linfen
* @since 2020-04-8
*/
@Component
public class QiniuUtil {
@Value("${qiniu.accessKey}")
private String accessKey ;
@Value("${qiniu.secretKey}")
private String secretKey ;
@Value("${qiniu.bucketName}")
private String bucketName ;
@Value("${qiniu.fileDomain}")
private String fileDomain;
public String getAccessKey() {
return accessKey;
}
public String getSecretKey() {
return secretKey;
}
public String getBucketName() {
return bucketName;
}
public String getFileDomain() {
return fileDomain;
}
private UploadManager uploadManager;
private BucketManager bucketManager;
private Configuration c;
private Client client;
// 密钥配置
private Auth auth;
public Client getClient(){
if (client==null) {
client=new Client(getConfiguration());
}
return client;
}
public BucketManager getBucketManager() {
if (bucketManager == null) {
bucketManager = new BucketManager(getAuth(), getConfiguration());
}
return bucketManager;
}
public UploadManager getUploadManager() {
if (uploadManager == null) {
uploadManager = new UploadManager(getConfiguration());
}
return uploadManager;
}
public Configuration getConfiguration() {
if (c == null) {
Zone z = Zone.autoZone();
c = new Configuration(z);
}
return c;
}
public Auth getAuth() {
if (auth == null) {
auth = Auth.create(getAccessKey(), getSecretKey());
}
return auth;
}
//简单上传模式的凭证
public String getUpToken() {
return getAuth().uploadToken(getBucketName());
}
//覆盖上传模式的凭证
public String getUpToken(String fileKey) {
return getAuth().uploadToken(getBucketName(), fileKey);
}
/**
* 将本地文件上传
* @param filePath 本地文件路径
* @param fileKey 上传到七牛后保存的文件路径名称
* @return
* @throws IOException
*/
public DefaultPutRet upload(String filePath, String fileKey) throws IOException {
Response res = getUploadManager().put(filePath, fileKey, getUpToken(fileKey));
// 解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(res.bodyString(), DefaultPutRet.class);
return putRet;
}
/**
* 上传二进制数据
* @param data
* @param fileKey
* @return
* @throws IOException
*/
public DefaultPutRet upload(byte[] data, String fileKey) throws IOException {
Response res = getUploadManager().put(data, fileKey, getUpToken(fileKey));
// 解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(res.bodyString(), DefaultPutRet.class);
return putRet;
}
/**
* 上传输入流
* @param inputStream
* @param fileKey
* @return
* @throws IOException
*/
public DefaultPutRet upload(InputStream inputStream, String fileKey) throws IOException {
Response res = getUploadManager().put(inputStream, fileKey, getUpToken(fileKey),null,null);
// 解析上传成功的结果
DefaultPutRet putRet = new Gson().fromJson(res.bodyString(), DefaultPutRet.class);
return putRet ;
}
/**
* 删除文件
* @param fileKey
* @return
* @throws QiniuException
*/
public boolean delete(String fileKey) throws QiniuException {
Response response = bucketManager.delete(this.getBucketName(), fileKey);
return response.statusCode == 200 ? true:false;
}
/**
* 获取公共空间文件
* @param fileKey
* @return
*/
public String getFile(String fileKey) throws Exception{
String encodedFileName = URLEncoder.encode(fileKey, "utf-8").replace("+", "%20");
String url = String.format("%s/%s", fileDomain, encodedFileName);
return url;
}
/**
* 获取私有空间文件
* @param fileKey
* @return
*/
public String getPrivateFile(String fileKey) throws Exception{
String encodedFileName = URLEncoder.encode(fileKey, "utf-8").replace("+", "%20");
String publicUrl = String.format("%s/%s", fileDomain, encodedFileName);
Auth auth = Auth.create(accessKey, secretKey);
long expireInSeconds = 3600;//1小时,可以自定义链接过期时间
String finalUrl = auth.privateDownloadUrl(publicUrl, expireInSeconds);
return finalUrl;
}
}
2.4创建控制类QiNiuController.java
import cn.hutool.core.date.DateUtil;
import cn.linfenw.log.annotation.SysOperaLog;
import cn.linfenw.modules.sys.util.QiniuUtil;
import com.alibaba.fastjson.JSON;
import com.qiniu.storage.model.DefaultPutRet;
import cn.linfenw.common.utils.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
/**
* 七牛云工具类
* @author linfen
* @since 2020-04-8
*/
@Slf4j
@RestController
@RequestMapping("/qiniu")
public class QiNiuController {
@Autowired
private QiniuUtil qiniuUtil;
/**
* 七牛云文件上传
*
* @param file 文件
* @return
*/
@RequestMapping("/upload")
@ResponseBody
public R upload(MultipartFile[] file) {
if (file.length <= 0) {
return R.error("上传文件不能为空");
}
if (file[0].isEmpty()) {
return R.error("上传文件不能为空");
}
try {
BufferedInputStream fileInputStream = (BufferedInputStream) file[0].getInputStream();
String originalFilename = file[0].getOriginalFilename();
String fileExtend = originalFilename.substring(originalFilename.lastIndexOf("."));
String yyyyMMddHHmmss = DateUtil.format(new Date(), "yyyyMMddHHmmss");
//默认不指定key的情况下,以文件内容的hash值作为文件名
String fileKey = UUID.randomUUID().toString().replace("-", "") + "-" + yyyyMMddHHmmss + fileExtend;
Map<String, Object> map = new HashMap<>();
DefaultPutRet uploadInfo = qiniuUtil.upload(fileInputStream, fileKey);
map.put("fileName", uploadInfo.key);
map.put("originName", originalFilename);
map.put("size", file[0].getSize());
//七牛云文件私有下载地址(看自己七牛云公开还是私有配置)
map.put("url", "/linfen/qiniu/private/file/" + uploadInfo.key);
// map.put("url", "/linfen/qiniu/file/" + uploadInfo.key);//七牛云公开下载地址
log.info("文件:" + JSON.toJSONString(map));
return R.ok(map);
} catch (Exception e) {
e.printStackTrace();
return R.error("上传失败");
}
}
/**
* 七牛云私有文件下载
*
* @param filename 文件名
* @return
*/
@RequestMapping("/private/file/{filename}")
public void privateDownload(@PathVariable("filename") String filename, HttpServletResponse response) {
if (filename.isEmpty()) {
return;
}
try {
String privateFile = qiniuUtil.getPrivateFile(filename);
log.info("文件下载地址:" + privateFile);
response.sendRedirect(privateFile);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 七牛云文件下载
*
* @param filename 文件名
* @return
*/
@RequestMapping("/file/{filename}")
public void download(@PathVariable("filename") String filename, HttpServletResponse response) {
if (filename.isEmpty()) {
return;
}
try {
String privateFile = qiniuUtil.getFile(filename);
log.info("文件下载地址:" + privateFile);
response.sendRedirect(privateFile);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 七牛云删除文件
*
* @param filename 文件名
* @return
*/
@SysOperaLog(descrption = "删除七牛云文件")
@PreAuthorize("hasAuthority('sys:qiniu:delete')")
@RequestMapping("/delete/file/{filename}")
public R deleteFile(@PathVariable("filename") String filename, HttpServletResponse response) {
if (filename.isEmpty()) {
return R.error("未知文件");
}
try {
boolean result = qiniuUtil.delete(filename);
if (result)
return R.ok("文件删除成功");
else
return R.error("文件删除失败");
} catch (Exception e) {
e.printStackTrace();
return R.error("文件删除失败");
}
}
}
3.Vue实现代码实现qiniuOss.vue
项目添加element的上传组件,前后端分离的项目需要携带token信息可以再headers中添加要携带的信息,代码如下
<template>
<div class="app-container">
<el-form
ref="dataForm"
:model="dataForm"
>
<el-form-item label="上传文件" prop="title" :label-width="formLabelWidth">
<el-upload
drag
action="/linfen/qiniu/upload"
:before-upload="handleUploadPreview"
:on-success="handleUploadSuccess"
:on-error="handleUploadError"
:limit="1"
:headers="uploadHeaders"
multiple>
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
<div class="el-upload__tip" slot="tip">文件不得超过25M</div>
</el-upload>
</el-form-item>
<el-form-item label="原文件名" prop="originName" :label-width="formLabelWidth">
<el-input :disabled="true" v-model="dataForm.originName" placeholder="请输入原文件名"/>
</el-form-item>
<el-form-item label="大小" prop="fileSize" :label-width="formLabelWidth">
<el-input :disabled="true" v-model="dataForm.fileSize" placeholder="请输入文件大小" />
</el-form-item>
<el-form-item label="下载地址" prop="url" :label-width="formLabelWidth">
<el-input :disabled="true" v-model="dataForm.url" placeholder="请输入下载地址" />
<el-link :underline="false" type="primary" :href="dataForm.url">下载</el-link>
</el-form-item>
</el-form>
</div>
</template>
<script>
import { getToken } from '@/utils/auth'
export default {
data() {
return {
formLabelWidth: '120px',
uploadHeaders:{},
dataForm: {
fileSize: '',
type: '',
downloads: '',
},
}
},
created() {
this.uploadHeaders={//设置授权的Token
'Authorization': 'Bearer ' + getToken(),
}
},
methods: {
clipboardSuccess() {
this.$message({
message: '复制成功',
type: 'success',
duration: 1500
})
},
handleUploadPreview(file) {//文件上传进行大小判断
console.log(file);
const isLt2M = file.size / 1024 / 1024 < 25;
if (!isLt2M) {
this.$message.error('上传文件大小不能超过 25MB!');
}
return isLt2M;
},
handleUploadSuccess(res, file) {//处理成功后的设置
if (res.code === 200) {
this.$message.success('上传成功')
this.dataForm.url = res.data.url
this.dataForm.fileSize = res.data.size
this.dataForm.originName = res.data.originName
console.log(JSON.stringify(this.dataForm))
} else {
this.$message.success(res.msg)
}
},
handleUploadError(err, file) {
this.$message.error("失败" + err)
},
}
}
</script>
三、运行效果
最终运行效果如下:
更多推荐
所有评论(0)