Spring Boot 利用WebUploader進(jìn)行文件上傳功能
Web Uploader簡(jiǎn)介
WebUploader是由Baidu WebFE(FEX)團(tuán)隊(duì)開發(fā)的一個(gè)簡(jiǎn)單的以HTML5為主,F(xiàn)LASH為輔的現(xiàn)代文件上傳組件。在現(xiàn)代的瀏覽器里面能充分發(fā)揮HTML5的優(yōu)勢(shì),同時(shí)又不摒棄主流IE瀏覽器,沿用原來(lái)的FLASH運(yùn)行時(shí),兼容IE6+,iOS 6+, android 4+。兩套運(yùn)行時(shí),同樣的調(diào)用方式,可供用戶任意選用。采用大文件分片并發(fā)上傳,極大的提高了文件上傳效率。
我們這里使用官網(wǎng)的一個(gè)例子來(lái)實(shí)現(xiàn)我們個(gè)人頭像的上傳。
我們的重點(diǎn)是在Spring Boot項(xiàng)目中利用WebUploader如何進(jìn)行文件上傳,所以直接實(shí)現(xiàn)一個(gè)簡(jiǎn)單的功能,僅供參考。
下面是一個(gè)從官網(wǎng)下載來(lái)的示例:帶剪裁的圖片上傳功能。

我們利用示例來(lái)改造項(xiàng)目中的個(gè)人頭像上傳。
效果看起來(lái)是這樣的:


首先我們來(lái)改造我們的WebUploader示例代碼。
以下都是我項(xiàng)目中的部分代碼:
(function( factory ) {
if ( !window.jQuery ) {
alert('jQuery is required.')
}
jQuery(function() {
factory.call( null, jQuery );
});
})
(function( $ ) {
// -----------------------------------------------------
// ------------ START ----------------------------------
// -----------------------------------------------------
// ---------------------------------
// --------- Uploader -------------
// ---------------------------------
var Uploader = (function() {
// -------setting-------
// 如果使用原始大小,超大的圖片可能會(huì)出現(xiàn) Croper UI 卡頓,所以這里建議先縮小后再crop.
var FRAME_WIDTH = 1600;
var _ = WebUploader;
var Uploader = _.Uploader;
var uploaderContainer = $('.uploader-container');
var uploader, file;
if ( !Uploader.support() ) {
alert( 'Web Uploader 不支持您的瀏覽器!');
throw new Error( 'WebUploader does not support the browser you are using.' );
}
// hook,
// 在文件開始上傳前進(jìn)行裁剪。
Uploader.register({
'before-send-file': 'cropImage'
}, {
cropImage: function( file ) {
var data = file._cropData,
image, deferred;
file = this.request( 'get-file', file );
deferred = _.Deferred();
image = new _.Lib.Image();
deferred.always(function() {
image.destroy();
image = null;
});
image.once( 'error', deferred.reject );
image.once( 'load', function() {
image.crop( data.x, data.y, data.width, data.height, data.scale );
});
image.once( 'complete', function() {
var blob, size;
// 移動(dòng)端 UC / qq 瀏覽器的無(wú)圖模式下
// ctx.getImageData 處理大圖的時(shí)候會(huì)報(bào) Exception
// INDEX_SIZE_ERR: DOM Exception 1
try {
blob = image.getAsBlob();
size = file.size;
file.source = blob;
file.size = blob.size;
file.trigger( 'resize', blob.size, size );
deferred.resolve();
} catch ( e ) {
console.log( e );
// 出錯(cuò)了直接繼續(xù),讓其上傳原始圖片
deferred.resolve();
}
});
file._info && image.info( file._info );
file._meta && image.meta( file._meta );
image.loadFromBlob( file.source );
return deferred.promise();
}
});
return {
init: function( selectCb ) {
uploader = new Uploader({
pick: {
id: '#filePicker',
multiple: false
},
// 設(shè)置用什么方式去生成縮略圖。
thumb: {
quality: 70,
// 不允許放大
allowMagnify: false,
// 是否采用裁剪模式。如果采用這樣可以避免空白內(nèi)容。
crop: false
},
// 禁掉分塊傳輸,默認(rèn)是開起的。
chunked: false,
// 禁掉上傳前壓縮功能,因?yàn)闀?huì)手動(dòng)裁剪。
compress: false,
// fileSingleSizeLimit: 2 * 1024 * 1024,
server: 'StudentImgFileUpload',
swf: $.trim($("#BASE_URL").val()) + '/static/webuploader/Uploader.swf',
fileNumLimit: 1,
// 只允許選擇圖片文件。
accept: {
title: 'Images',
// extensions: 'gif,jpg,jpeg,bmp,png',
// mimeTypes: 'image/*'
extensions: 'jpg,jpeg,png',
//解決WebUploader chrome 點(diǎn)擊上傳文件選擇框會(huì)延遲幾秒才會(huì)顯示 反應(yīng)很慢
mimeTypes: 'image/jpg,image/jpeg,image/png' //修改這行
}
//formData: {"Authorization": localStorage.token}, //額外參數(shù)傳遞,可以沒(méi)有
// chunked: true, //分片
// chunkSize: 10 * 1024 * 1024, //分片大小指定
// threads:1, //線程數(shù)量
// disableGlobalDnd: true //禁用拖拽
// onError: function() {
// var args = [].slice.call(arguments, 0);
// alert(args.join('\n'));
// }
});
uploader.on('fileQueued', function( _file ) {
file = _file;
uploader.makeThumb( file, function( error, src ) {
if ( error ) {
alert('不能預(yù)覽');
return;
}
selectCb( src );
}, FRAME_WIDTH, 1 ); // 注意這里的 height 值是 1,被當(dāng)成了 100% 使用。
});
/**
* 驗(yàn)證文件格式以及文件大小
*/
uploader.on("error", function (type) {
if (type == "Q_TYPE_DENIED") {
showInfo("請(qǐng)上傳JPG、JEPG、PNG、格式文件");
}
});
// 文件上傳成功,給item添加成功class, 用樣式標(biāo)記上傳成功。
uploader.on( 'uploadSuccess', function( file ) {
showInfo("上傳成功");
});
// 文件上傳失敗,顯示上傳出錯(cuò)。
uploader.on( 'uploadError', function( file ) {
showInfo("上傳失敗");
});
},
crop: function( data ) {
var scale = Croper.getImageSize().width / file._info.width;
data.scale = scale;
file._cropData = {
x: data.x1,
y: data.y1,
width: data.width,
height: data.height,
scale: data.scale
};
},
upload: function() {
uploader.upload();
}
}
})();
// ---------------------------------
// --------- Crpper ---------------
// ---------------------------------
var Croper = (function() {
var container = $('.cropper-wraper');
var $image = container.find('.img-container img');
var btn = $('.upload-btn');
var isBase64Supported, callback;
$image.cropper({
aspectRatio: 4 / 4,
preview: ".img-preview",
done: function(data) {
// console.log(data);
}
});
function srcWrap( src, cb ) {
// we need to check this at the first time.
if (typeof isBase64Supported === 'undefined') {
(function() {
var data = new Image();
var support = true;
data.onload = data.onerror = function() {
if( this.width != 1 || this.height != 1 ) {
support = false;
}
}
data.src = src;
isBase64Supported = support;
})();
}
if ( isBase64Supported ) {
cb( src );
} else {
// otherwise we need server support.
// convert base64 to a file.
// $.ajax('', {
// method: 'POST',
// data: src,
// dataType:'json'
// }).done(function( response ) {
// if (response.result) {
// cb( response.result );
// } else {
// alert("預(yù)覽出錯(cuò)");
// }
// });
}
}
btn.on('click', function() {
callback && callback($image.cropper("getData"));
return false;
});
return {
setSource: function( src ) {
// 處理 base64 不支持的情況。
// 一般出現(xiàn)在 ie6-ie8
srcWrap( src, function( src ) {
$image.cropper("setImgSrc", src);
});
container.removeClass('webuploader-element-invisible');
return this;
},
getImageSize: function() {
var img = $image.get(0);
return {
width: img.naturalWidth,
height: img.naturalHeight
}
},
setCallback: function( cb ) {
callback = cb;
return this;
},
disable: function() {
$image.cropper("disable");
return this;
},
enable: function() {
$image.cropper("enable");
return this;
}
}
})();
// ------------------------------
// -----------logic--------------
// ------------------------------
var container = $('.uploader-container');
Uploader.init(function( src ) {
Croper.setSource( src );
// 隱藏選擇按鈕。
container.addClass('webuploader-element-invisible');
// 當(dāng)用戶選擇上傳的時(shí)候,開始上傳。
Croper.setCallback(function( data ) {
Uploader.crop(data);
Uploader.upload();
});
});
// -----------------------------------------------------
// ------------ END ------------------------------------
// -----------------------------------------------------
});
還有頁(yè)面的部分代碼:
下面是Controller部分的代碼:
@RequestMapping(value="/student/StudentImgFileUpload", method=RequestMethod.POST)
@ResponseBody
String studentImgFileUpload(@RequestParam MultipartFile file, HttpServletRequest request){
logger.info("學(xué)生頭像上傳....")
//獲取文件名
String originalFilename = file.getOriginalFilename()
logger.info("上傳文件名:" + originalFilename)
String realPath = request.getServletContext().getRealPath("/public/student/")
String uploadFileName = System.currentTimeMillis()+"_"+ originalFilename
logger.info("獲取上傳路徑:" + realPath + ", 上傳的真實(shí)文件名:" + uploadFileName)
boolean flag = true
//合并文件
RandomAccessFile raFile = null
BufferedInputStream inputStream = null
try{
File dirFile = new File(realPath, uploadFileName)
//以讀寫的方式打開目標(biāo)文件
raFile = new RandomAccessFile(dirFile, "rw")
raFile.seek(raFile.length())
inputStream = new BufferedInputStream(file.getInputStream())
byte[] buf = new byte[1024]
int length = 0
while ((length = inputStream.read(buf)) != -1) {
raFile.write(buf, 0, length)
}
}catch(Exception e){
flag = false
logger.info("上傳出錯(cuò):" + e.getMessage())
throw new IOException(e.getMessage())
}finally{
try {
if (inputStream != null) {
inputStream.close()
}
if (raFile != null) {
raFile.close()
}
}catch(Exception e){
flag = false
logger.info("上傳出錯(cuò):" + e.getMessage())
throw new IOException(e.getMessage())
}
}
}
這樣就簡(jiǎn)單實(shí)現(xiàn)了在Spring Boot項(xiàng)目中使用WebUploader進(jìn)行文件上傳的功能。
總結(jié)
以上所述是小編給大家介紹的Spring Boot 利用WebUploader進(jìn)行文件上傳功能,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Spring Boot Actuator監(jiān)控端點(diǎn)小結(jié)
這篇文章主要介紹了Spring Boot Actuator監(jiān)控端點(diǎn)小結(jié),需要的朋友可以參考下2017-06-06
如何修改覆蓋spring boot默認(rèn)日志策略logback詳解
這篇文章主要給大家介紹了關(guān)于如何修改覆蓋spring boot默認(rèn)日志策略logback的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2018-10-10
Java靜態(tài)static關(guān)鍵字原理詳解
這篇文章主要介紹了Java靜態(tài)static關(guān)鍵字原理詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
Spring Validation方法實(shí)現(xiàn)原理分析
這篇文章主要介紹了Spring Validation實(shí)現(xiàn)原理分析,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-07-07
java使用FFmpeg合成視頻和音頻并獲取視頻中的音頻等操作(實(shí)例代碼詳解)
這篇文章主要介紹了java使用FFmpeg合成視頻和音頻并獲取視頻中的音頻等操作,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-02-02

