背景
之前在后端上传视频到七牛云上,发现上传速度很慢,后来尝试直接在前端上传视频到七牛云上,最后实测发现快了很多。采用前端上传也减轻了服务器压力。
除了七牛云,当然也可以考虑阿里云对象存储oss
参考
七牛云存储示例:http://jssdk.demo.qiniu.io/
官方SDK:https://developer.qiniu.com/kodo/sdk/1283/javascript
swf文件下载SDK里面有
下载地址:https://github.com/qiniu/js-sdk/releases
步骤
视频上传
1、后台生成token字符串给前端:
pom文件引入
<!-- qiniu -->
<dependency>
<groupId>com.qiniu</groupId>
<artifactId>qiniu-java-sdk</artifactId>
<version>[7.2.0, 7.2.99]</version>
</dependency>
QiNiuUtil工具类
package com.jcmx.common.utils;
import com.google.gson.Gson;
import com.qiniu.common.QiniuException;
import com.qiniu.common.Zone;
import com.qiniu.http.Response;
import com.qiniu.storage.Configuration;
import com.qiniu.storage.UploadManager;
import com.qiniu.storage.model.DefaultPutRet;
import com.qiniu.util.Auth;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.FileInputStream;
import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
public class QiNiuUtil {
static Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
public static final String accessKey = "";//公钥
public static final String secretKey = "";//秘钥
public static final String bucket = "";//空间名
public static final String path = "";//加速域名
public static String uploadToken(FileInputStream file, String key) {
Configuration cfg = new Configuration(Region.region0());//华东地区
UploadManager uploadManager = new UploadManager(cfg);
logger.info("path=" + path);
try {
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
System.out.println("token:"+upToken);
//初始化时区对象,北京时间是UTC+8,所以入参为8
ZoneOffset zoneOffset=ZoneOffset.ofHours(8);
//初始化LocalDateTime对象
LocalDateTime localDateTime=LocalDateTime.now();
//获取LocalDateTime对象对应时区的Unix时间戳
System.out.println(localDateTime.toEpochSecond(zoneOffset));
Long e = localDateTime.toEpochSecond(zoneOffset);
try {
Response response = uploadManager.put(file, key, upToken, null, null);
//解析上传成功的结果
//DefaultPutRet putRet = JSON.parseObject(response.bodyString(), DefaultPutRet.class);
DefaultPutRet putRet = new Gson().fromJson(response.bodyString(), DefaultPutRet.class);
logger.info("key:" + putRet.key);
String encodedFileName = URLEncoder.encode(putRet.key, "utf-8");
//获取下载地址
/*String finalUrl1 = path+"/"+putRet.key;*/
String finalUrl = String.format("%s/%s", path, encodedFileName);//七牛云公有空间
String finalUrl1 = auth.privateDownloadUrl(finalUrl,e);//七牛云私有空间路径访问需给路径授权
logger.info("访问地址:" + finalUrl1);
return finalUrl1;
} catch (QiniuException ex) {
Response r = ex.response;
System.err.println(r.toString());
try {
System.err.println(r.bodyString());
} catch (QiniuException ex2) {
//ignore
}
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
/**生成Token*/
public static String getToken() {
Auth auth = Auth.create(accessKey, secretKey);
String upToken = auth.uploadToken(bucket);
return upToken;
}
}
生成token
//七牛Token
@GetMapping("/gettoken")
@ResponseBody
public Map<String,Object> uptoken(){
Map<String,Object> resultMap = new HashMap<>();
String token = QiNiuUtil.getToken();
resultMap.put("uptoken",token);
return resultMap;
}
2、编写前端代码:
导入JS文件(这里我就不贴代码了,通过七牛云存储示例F12就可以看到对应的JS和css,拷贝到自己的项目里就可以了)
这里我把自己整理的js传到了GitHub上了,下载地址:https://github.com/CAPTAIN-JIE/qiniuUpload.git
这是我整理后放到项目里的js目录
页面引入JS文件
<script th:src="@{/js/jquery.min.js}"></script>
<script th:src="@{/js/qiniu/ui.js}"></script>
<script th:src="@{/js/qiniu/qiniu.min.js}"></script>
<script th:src="@{/js/qiniu/highlight.js}"></script>
<script th:src="@{/js/qiniu/main.js}"></script>
<script th:src="@{/js/bootstrap.min.js}"></script>
<script type="text/javascript">hljs.initHighlightingOnLoad();</script>
引入css样式
<link th:href="@{/css/main.css}" rel="stylesheet"/>
Html页面上传视频按钮
<div class="form-group">
<label class="col-sm-3 control-label">视频文件:</label>
<div class="col-sm-8">
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active" id="demo" aria-labelledby="demo-tab">
<div class="row" style="margin-top: 20px;">
<div class="col-md-12">
<div id="container">
<a class="layui-btn" id="pickfiles" href="#" >
<i class="fa fa-cloud-upload"></i>
<span>选择文件</span>
</a>
<span class="lbl col-xs-10" style="height: 38px; line-height: 38px;">
<span class="red">请上传800M以内的MP4文件</span>
</span>
</div>
<button type="button" class="layui-btn" id="videoRevoke" style="display: none;">
<i class="fa fa-undo"></i>撤销视频
</button>
</div>
<div style="display:none" id="success" class="col-md-12">
<div class="alert-success">
队列全部文件处理完毕
</div>
</div>
<div class="col-md-12" >
<table id="uploadInfo" class="table table-striped table-hover text-left" style="margin-top:40px;display:none">
<thead>
<tr>
<th class="col-md-4">Filename</th>
<th class="col-md-2">Size</th>
<th class="col-md-6">Detail</th>
</tr>
</thead>
<tbody id="fsUploadProgress">
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
JavaScript编写
/*撤销视频*/
$('#videoRevoke').bind('click',function(){
$("#container").css("display","block");
$('#success').css("display","none");
$('#videoRevoke').css("display","none");
$('#video_url').remove();
$('#fsUploadProgress>tr').remove();
})
通过隐藏标签获取上传视频路径传到后端保存到数据库
var resourcesUrl = document.getElementById("video_url").src;
到此上传视频的功能就完成了。
图片上传
下面贴上上传图片的方法(因为图片比较小,对速度影响不大,这里我是通过后端上传的图片)
1、前端代码编写:
Html页面上传图片按钮
<div class="form-group">
<label class="col-sm-3 control-label">封面:</label>
<div class="col-sm-8">
<div class="layui-form-item" id="imageUp">
<input name="image_url" id="image_url" autocomplete="off" class="layui-input" type="hidden">
<button type="button" class="layui-btn" id="imageupload">
<i class="fa fa-cloud-upload"></i>上传图片
</button>
<button type="button" class="layui-btn" id="imageRevoke">
<i class="fa fa-undo"></i>撤销图片
</button>
<input class="layui-upload-file" type="file" accept="images" name="file">
<span class="lbl col-xs-10" style="height: 38px; line-height: 38px;display: block;">
<span class="red">请上传尺寸为750*440的图片!</span>
</span>
<p id="demoText1"></p>
</div>
<div class="layui-upload-list" id="previewBox">
<div class="imgBox">
<img class="layui-upload-img" id="imgs">
</div>
</div>
</div>
</div>
JavaScript编写
/*撤销图片*/
$('#imageRevoke').bind('click',function(){
var imgobj = document.getElementById('imgs');
imgobj.removeAttribute('src');
$("#imageupload").attr("disabled",false);
$('#msg').css("display","none");
var imageUrl = document.getElementById('image_url');
imageUrl.removeAttribute('src');
})
<script>
layui.use('upload', function(){
var $ = layui.jquery
,upload = layui.upload;
//上传图片
var uploadInst =upload.render({
elem: '#imageupload'
,url: '/app/informationTime/uploadImage'
,field:"uploadImage"
,choose: function(obj) {// 选择文件之后,提交文件之前,你想干什么?
obj.preview(function (index, file, result) {
if (file.size > 0) {// 判断文件大小
flag = true;
layer.msg("正在上传!");// 此段话,用来拖延用户点击提交按钮的时间,因为不知道covers是否返回
}
})
}
,done: function(res) {
$('#image_url').attr("src",res.data);
$('#imgs').attr("src",res.data);
var demoText = $('#demoText1');
demoText.html('<span id="msg" style="color: #ff5722;" style="display: block;">上传成功!</span>');
$("#imageupload").attr("disabled",true);
}
,error:function () {
//演示失败状态,并实现重传
var demoText = $('#demoText1');
demoText.html('<span id="msg" style="color: #FF5722;" style="display: block;">上传失败!</span> <a class="layui-btn layui-btn-mini demo-reload">重试</a>');
demoText.find('.demo-reload').on('click', function () {
uploadInst.upload();
});
}
});
});
</script>
2、后台代码:
@ApiOperation(value = "上传图片")
@PostMapping("/uploadImage")
@ResponseBody
public Editor uploadImage(@RequestParam("uploadImage") MultipartFile multiple, HttpSession session, HttpServletRequest request) throws IOException {
if (multiple != null) {
String [] str = upload(multiple);
return Editor.ResultUtil.success(str);
}
return Editor.ResultUtil.success();
}
public String [] upload(MultipartFile multiple){
FileInputStream inputStream = null;
try {
inputStream = (FileInputStream) multiple.getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
String fileName = multiple.getOriginalFilename();
String fileNameExtension = fileName.substring(fileName.lastIndexOf("."), fileName.length());
String realName = String.valueOf(System.currentTimeMillis()) + ShiroUtils.getLoginName() + fileNameExtension;
String path = QiNiuUtil.uploadToken(inputStream, realName);
String [] str = {path};
return str;
}
以上是js上传文件到七牛云上的步骤,欢迎大家提供好的建议!