本人懒,所以只用简单有效的方法,照我的方法做,实现不了,你来砍我。
还是那句话,会的人不用看,不会的人看不懂的教程,我是不会出的,我这都是给小白的上岸和避坑教程。
本教程不涉及七牛云的注册、域名管理、空间管理等等内容,需要了解相关内容的请自行查阅官方文档。
废话不多说,开整!!!
后台:springboot
pom.xml引入依赖
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.16.0, 7.16.99]</version>
</dependency>
写个七牛工具类qiNiuUtil.java,用来完成上传和读取操作
package com.hz.myplugins.qiNiu;
import com.alibaba.fastjson.JSONObject;
import com.qiniu.util.Auth;
import com.qiniu.util.StringMap;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import java.net.URLEncoder;
@Controller
@RequestMapping("/qiniu")
public class qiNiuUtil{
private static String accessKey = "你的七牛key";
private static String secretKey = "你的七牛secret";
private static String domainOfBucket = "你在七牛设置的快速域名";
@RequestMapping("/qiniu_getTokenUrl")
@ApiOperation(value = "获取上传token")
@ResponseBody //实现数据接口
public JSONObject qiniu_getTokenUrl( @RequestParam(value="filename", defaultValue = "") String filename){
String upToken ="";
try {
/**
*我做的是覆盖上传,也就是同路径下的同名文件会被覆盖,这样做的好处是简化空间管理成本,而且会最大限度的提升空间的使用率,避免不必要的垃圾文件。
*/
Auth auth = Auth.create(accessKey, secretKey);
String bucket = "你的空间名称";
//配置允许覆盖参数
StringMap policy = new StringMap();
policy.put("insertOnly",0);
policy.put("scope",bucket+":"+filename);
/**覆盖上传,需要将filename作为key值(auth.uploadToken方法的第二个参数)进行验签,并回传给前台上传方法,
*前台上传时,同样要将该路径(filename),作为参数“Key”的值一并提交,否则覆盖上传会出错。
*需要注意的是,即便是覆盖上传,被覆盖的图片也不会立马被替换掉,大概会过5分钟左右才会生效!也就是说,你上传完新文件,拿到的回调链接,显示的图片还是旧的,需要等5分钟左右才会生效,所以不要慌,让子弹飞一会儿。
*如果不考虑覆盖上传则无需上面的参数配置 下面方法直接用auth.uploadToken(bucket)即可*/
//拿到的upToken回传给前端(因为我是前端上传文件,别问为什么,问就是因为懒!)
upToken = auth.uploadToken(bucket, filename,3600,policy);
} catch (Exception e) {
e.printStackTrace();
}
JSONObject map = new JSONObject();
map.put("code",200);
map.put("upToken",upToken);
return map;
}
//如果是公开访问的空间,则不需要下面的方法,这个方法是私有空间的相对文件路径,换取文件完整网络路径时用的
@RequestMapping("/getmediaurl")
@ApiOperation(value = "获取私有图片链接")
@ResponseBody //实现数据接口
public JSONObject getmediaurl( @RequestParam(value="filename", defaultValue = "") String filename){
String finalUrl = "";
try {
String encodedFileName = URLEncoder.encode(filename, "utf-8").replace("+", "%20");
String publicUrl = String.format("%s/%s", domainOfBucket, encodedFileName);
Auth auth = Auth.create(accessKey, secretKey);
long expireInSeconds = 3600;//1小时,可以自定义链接过期时间
finalUrl = auth.privateDownloadUrl(publicUrl, expireInSeconds);
System.out.println(finalUrl);
}catch (Exception e){
System.out.println(e.getMessage());
}
JSONObject map = new JSONObject();
map.put("code",200);
map.put("mediaurl",finalUrl);
return map;
}
}
vue前端上传代码,我用的是element框架
<!--ElementUI上传组件,内部样式你自己调整-->
<el-upload
action="https://upload-z1.qiniup.com" //我用了代理上传方法,所以action绑定的上传路径会失效
:limit="9"
:http-request="sliderRequest" //这里是代理上传方法
:before-upload="handleUpload"
:on-error="handleError"
multiple
:show-file-list="false"
ref="uploadimg"
>
<div v-if="user.user_avatar!=null&&user.user_avatar.length>0" >
<img :src="user.user_avatar" class="avatar2 border" />
</div>
<i v-else class="el-icon-plus avatar-uploader-icon border"></i>
</el-upload>
let _this;
//Vue生命周期 data()
data() {
return {
user:{
user_name:"鲁班七号",
user_avatar:""
},
qiniu_url:"你自己的七牛加速域名,也可以配置为全局常量"
}
},
//Vue生命周期 mounted()
mounted() {
//生命周期内 _this 一次性赋值
_this = this;
},
//Vue生命周期 methods
methods: {
sliderRequest(upload) {
// 创建FormData对象 添加相关上传参数
const formData = new FormData()
// 添加file参数,并绑定文件对象
formData.append('file', upload.file)
let filename ="miniPro/user/"+_this.user.user_name+"/"+ upload.file.name;
//此时的文件名filename值(例)为:miniPro/user/鲁班七号/头像.jpg
// 添加key参数,并绑定文件路径,这个key的作用,后台注释里说了
formData.append('key', filename)
//用你喜欢的方式从后台获取上传Token,别说你不会请求后台接口(大嘴巴子)
getqiniuToken(filename).then(qiniures=>{
// 将上传token添加为参数
formData.append('token', qiniures.upToken);
//这里注意你的目标url一定要是你七牛云注册区域的地址,不知道自己区域地址的,自己去官方查。
axios.post("https://upload-z1.qiniup.com", formData,
{
onUploadProgress: (event) => {
// 监听上传进度
event.percent = event.loaded / event.total * 100
upload.onProgress(event)
}
}).then((response) => {
//上传成功后调取自定义成功方法
if (response.status === 200) {
_this.handleQiniuSuccess(filename);
}
}).catch((err) => {
// 调用组件上传失败方法
_this.handleError();
})
})
},
handleQiniuSuccess(filename) {
//我这里以“七牛公开访问的空间”为例,加速域名+文件相对路径,就可以直接访问到图片
_this.user.user_avatar= _this.qiniu_url+filename;
/**如果你的空间是私有空间,那么只需要保存相对路径即可
*_this.user.user_avatar= filename;
*读取的时候,调用后台的getmediaurl方法,把相对路径作为参数传进去,换取图片的临时网络路径,进行读取
*/
//清空一下上传组件 否则不能二次上传
_this.$refs.uploadimg.clearFiles();
}
}
okkkkkkk 下面是小程序端
//注意:我在页面加载时把已经把this赋值给全局变量vm了
//小程序生命周期内方法
ChooseImage(e) {
//因为用户上传到小程序的图片的文件名会被转码,所以为了方便管理,我自己重新给他命名
//这个key值就会作为最终的文件名来保存起来,我这个key选用的是字段名
let key = e.currentTarget.dataset.key;
wx.chooseMedia({
count: 1,//可选媒体数量
mediaType: ['image','video'],//可选媒体类型
sourceType: ['album', 'camera'],
success: (res) => {
let img = res.tempFiles[0];
let imgpath = img.tempFilePath;
//赠送大家一个图片压缩代码 因为你不知道那些用户会上传些什么东西
wx.showLoading({
title: '图片处理中',
})
if(img.size>1048576){
let scale = Math.floor(1048576/img.size*100);
//console.log("压缩比例",scale)
wx.compressImage({
src: imgpath, // 图片路径
quality:scale, // 压缩质量
success:(reimg)=>{
wx.hideLoading();
//压缩完成,启动上传
vm.uploadpic(reimg.tempFilePath,key);
}})
}else{
wx.hideLoading();
//无需压缩,直接上传
vm.uploadpic(imgpath,key);
}
}
});
},
uploadpic(upload,key){
//对不起,这里我只是要一个扩展名,参数里的key是我的文件名
let patharray = upload.split(".");
let filename ="miniPro/user/"+ key +"."+ patharray[patharray.length-1];
let formData = {
key:filename
}
//因为业务需要 我重新封装了wx.request,变成tools.request
//你用wx.request也是一样的
tools.request("后台地址" + 'qiniu/qiniu_getTokenUrl',"get",
{
filename
}).then(function (qiniures) {
formData.token = qiniures.data.upToken;
//提交前上传业务前,也必须要添加key、token两个关键参数
//和vue不同的是,小程序是将文件的临时路径作为文件标识,由wx.uploadFile方法提取出文件的
//所以我们不用自己添加文件参数(你也拿不到文件)
wx.uploadFile({
url: 'https://upload-z1.qiniup.com',
filePath: upload,//这里的upload就是文件的临时路径
name: 'file',
formData,
success (res){
//到这里上传就完成了,你可以根据自己需要(公开还是私有空间)来保存文件链接
//公开文件链接:你的七牛快速域名+filename(上面的变量)
//私有文件链接:filename(读取图片时,需要携带此路径去后台请求getmediaurl方法)
//用相对路径换取图片临时网络路径
}
})
});
},
我总结了很多其他教程里说的云里雾里的问题,比如覆盖上传问题,比如Key值问题,比如参数问题、区域问题等等,一口气说明白,包教包会!!!!!!