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瀏覽器,沿用原來的FLASH運(yùn)行時(shí),兼容IE6+,iOS 6+, android 4+。兩套運(yùn)行時(shí),同樣的調(diào)用方式,可供用戶任意選用。采用大文件分片并發(fā)上傳,極大的提高了文件上傳效率。
我們這里使用官網(wǎng)的一個(gè)例子來實(shí)現(xiàn)我們個(gè)人頭像的上傳。
我們的重點(diǎn)是在Spring Boot項(xiàng)目中利用WebUploader如何進(jìn)行文件上傳,所以直接實(shí)現(xiàn)一個(gè)簡(jiǎn)單的功能,僅供參考。
下面是一個(gè)從官網(wǎng)下載來的示例:帶剪裁的圖片上傳功能。
我們利用示例來改造項(xiàng)目中的個(gè)人頭像上傳。
效果看起來是這樣的:
首先我們來改造我們的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 瀏覽器的無圖模式下 // 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ù)傳遞,可以沒有 // 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 ------------------------------------ // ----------------------------------------------------- });
還有頁面的部分代碼:
下面是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ì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
相關(guān)文章
Java Callable接口實(shí)現(xiàn)細(xì)節(jié)詳解
這篇文章主要介紹了Java Callable接口實(shí)現(xiàn)細(xì)節(jié)詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-05-05Mybatis?plus多租戶方案的實(shí)戰(zhàn)踩坑記錄
MybaitsPlus多租戶處理器是一個(gè)對(duì)于多租戶問題的解決方案,下面這篇文章主要給大家介紹了關(guān)于Mybatis?plus多租戶方案踩坑的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-12-12springboot整合security和vue的實(shí)踐
本文主要介紹了springboot整合security和vue的實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09詳解IDEA啟動(dòng)多個(gè)微服務(wù)的配置方法
這篇文章主要介紹了詳解IDEA啟動(dòng)多個(gè)微服務(wù)的配置方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-01-01詳解Java設(shè)計(jì)模式編程中的Flyweight享元模式的開發(fā)結(jié)構(gòu)
這篇文章主要介紹了Java設(shè)計(jì)模式編程中的Flyweight享元模式的開發(fā)結(jié)構(gòu),享元模式能夠最大限度地重用現(xiàn)有的同類對(duì)象,需要的朋友可以參考下2016-04-04JDK1.8中ConcurrentHashMap中computeIfAbsent死循環(huán)bug問題
這篇文章主要介紹了JDK1.8中ConcurrentHashMap中computeIfAbsent死循環(huán)bug,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08