webuploader結合SpringMVC實現多圖片上傳(附原始碼)
本案例實現多圖片上傳並且可以在前端預覽圖片,後端使用SpringMVC框架接收檔案,文章最後附原始碼。
一、效果
二、前端
#####1、呈現介面 —— index.jsp
<%@ page contentType="text/html; charset=utf-8" %> <html lang="zh-CN"> <head> <title>上傳Logo</title> <link rel="stylesheet" type="text/css" href="css/webuploader.css" /> <link rel="stylesheet" type="text/css" href="css/style.css" /> </head> <body> <div id="wrapper"> <div id="container"> <!--頭部,相簿選擇和格式選擇--> <div id="uploader"> <div class="queueList"> <div id="dndArea" class="placeholder"> <div id="filePicker"></div> <p>或將照片拖到這裡</p> </div> </div> <div class="statusBar" style="display:none;"> <div class="progress"> <span class="text">0%</span> <span class="percentage"></span> </div><div class="info"></div> <div class="btns"> <div id="filePicker2"></div><div class="uploadBtn">開始上傳</div> </div> </div> </div> </div> </div> <script type="text/javascript" src="js/jquery.js"></script> <script type="text/javascript" src="js/webuploader.js"></script> <script type="text/javascript" src="js/upload.js"></script> </body> </html>
#####2、upload.js
(function( $ ){ // 當domReady的時候開始初始化 $(function() { var $wrap = $('#uploader'), // 圖片容器 $queue = $( '<ul class="filelist"></ul>' ) .appendTo( $wrap.find( '.queueList' ) ), // 狀態列,包括進度和控制按鈕 $statusBar = $wrap.find( '.statusBar' ), // 檔案總體選擇資訊。 $info = $statusBar.find( '.info' ), // 上傳按鈕 $upload = $wrap.find( '.uploadBtn' ), // 沒選擇檔案之前的內容。 $placeHolder = $wrap.find( '.placeholder' ), $progress = $statusBar.find( '.progress' ).hide(), // 新增的檔案數量 fileCount = 0, // 新增的檔案總大小 fileSize = 0, // 優化retina, 在retina下這個值是2 ratio = window.devicePixelRatio || 1, // 縮圖大小 thumbnailWidth = 110 * ratio, thumbnailHeight = 110 * ratio, // 可能有pedding, ready, uploading, confirm, done. state = 'pedding', // 所有檔案的進度資訊,key為file id percentages = {}, // 判斷瀏覽器是否支援圖片的base64 isSupportBase64 = ( function() { var data = new Image(); var support = true; data.onload = data.onerror = function() { if( this.width != 1 || this.height != 1 ) { support = false; } } data.src = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw=="; return support; } )(), // WebUploader例項 uploader; if ( !WebUploader.Uploader.support('flash') && WebUploader.browser.ie ) { // flash 安裝了但是版本過低。 if (flashVersion) { (function(container) { window['expressinstallcallback'] = function( state ) { switch(state) { case 'Download.Cancelled': alert('您取消了更新!') break; case 'Download.Failed': alert('安裝失敗') break; default: alert('安裝已成功,請重新整理!'); break; } delete window['expressinstallcallback']; }; var swf = './expressInstall.swf'; // insert flash object var html = '<object type="application/' + 'x-shockwave-flash" data="' + swf + '" '; if (WebUploader.browser.ie) { html += 'classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '; } html += 'width="100%" height="100%" style="outline:0">' + '<param name="movie" value="' + swf + '" />' + '<param name="wmode" value="transparent" />' + '<param name="allowscriptaccess" value="always" />' + '</object>'; container.html(html); })($wrap); // 壓根就沒有安轉。 } else { $wrap.html('<a href="http://www.adobe.com/go/getflashplayer" target="_blank" border="0"><img alt="get flash player" src="http://www.adobe.com/macromedia/style_guide/images/160x41_Get_Flash_Player.jpg" /></a>'); } return; } else if (!WebUploader.Uploader.support()) { alert( 'Web Uploader 不支援您的瀏覽器!'); return; } // 例項化 uploader = WebUploader.create({ pick: { id: '#filePicker', label: '點選選擇圖片' }, formData: { uid1: 123 }, dnd: '#dndArea', paste: '#uploader', swf: '../other/Uploader.swf', chunked: false, chunkSize: 512 * 1024, server: 'upload', accept: { title: 'Images', extensions: 'png', mimeTypes: 'image/*' }, // 禁掉全域性的拖拽功能。這樣不會出現圖片拖進頁面的時候,把圖片開啟。 disableGlobalDnd: true, fileNumLimit: 300, fileSizeLimit: 200 * 1024 * 1024, // 200 M fileSingleSizeLimit: 50 * 1024 * 1024 // 50 M }); //console.log("js獲取的id:"+my_id); uploader.options.formData.uid = 111123; // 拖拽時不接受 js, txt 檔案。 uploader.on( 'dndAccept', function( items ) { var denied = false, len = items.length, i = 0, // 修改js型別 unAllowed = 'text/plain;application/javascript '; for ( ; i < len; i++ ) { // 如果在列表裡面 if ( ~unAllowed.indexOf( items[ i ].type ) ) { denied = true; break; } } return !denied; }); uploader.on('dialogOpen', function() { }); // 新增“新增檔案”的按鈕, uploader.addButton({ id: '#filePicker2', label: '繼續新增' }); uploader.on( 'uploadBeforeSend', function( obj, data, headers) { //data.formData{"my_id":123, "my_name":'測試name'}; }); uploader.on('ready', function() { window.uploader = uploader; }); // 當有檔案新增進來時執行,負責view的建立 function addFile( file ) { var $li = $( '<li id="' + file.id + '">' + '<p class="title">' + file.name + '</p>' + '<p class="imgWrap"></p>'+ '<p class="progress"><span></span></p>' + '</li>' ), $btns = $('<div class="file-panel">' + '<span class="cancel">刪除</span>' + '<span class="rotateRight">向右旋轉</span>' + '<span class="rotateLeft">向左旋轉</span></div>').appendTo( $li ), $prgress = $li.find('p.progress span'), $wrap = $li.find( 'p.imgWrap' ), $info = $('<p class="error"></p>'), showError = function( code ) { switch( code ) { case 'exceed_size': text = '檔案大小超出'; break; case 'interrupt': text = '上傳暫停'; break; default: text = '上傳失敗,請重試'; break; } $info.text( text ).appendTo( $li ); }; if ( file.getStatus() === 'invalid' ) { showError( file.statusText ); } else { // @todo lazyload $wrap.text( '預覽中' ); uploader.makeThumb( file, function( error, src ) { var img; if ( error ) { $wrap.text( '不能預覽' ); return; } if( isSupportBase64 ) { img = $('<img src="'+src+'">'); $wrap.empty().append( img ); } else { $.ajax('../../server/preview.php', { method: 'POST', data: src, dataType:'json' }).done(function( response ) { if (response.result) { img = $('<img src="'+response.result+'">'); $wrap.empty().append( img ); } else { $wrap.text("預覽出錯"); } }); } }, thumbnailWidth, thumbnailHeight ); percentages[ file.id ] = [ file.size, 0 ]; file.rotation = 0; } file.on('statuschange', function( cur, prev ) { if ( prev === 'progress' ) { $prgress.hide().width(0); } else if ( prev === 'queued' ) { $li.off( 'mouseenter mouseleave' ); $btns.remove(); } // 成功 if ( cur === 'error' || cur === 'invalid' ) { console.log( file.statusText ); showError( file.statusText ); percentages[ file.id ][ 1 ] = 1; } else if ( cur === 'interrupt' ) { showError( 'interrupt' ); } else if ( cur === 'queued' ) { $info.remove(); $prgress.css('display', 'block'); percentages[ file.id ][ 1 ] = 0; } else if ( cur === 'progress' ) { $info.remove(); $prgress.css('display', 'block'); } else if ( cur === 'complete' ) { $prgress.hide().width(0); $li.append( '<span class="success"></span>' ); } $li.removeClass( 'state-' + prev ).addClass( 'state-' + cur ); }); $li.on( 'mouseenter', function() { $btns.stop().animate({height: 30}); }); $li.on( 'mouseleave', function() { $btns.stop().animate({height: 0}); }); $btns.on( 'click', 'span', function() { var index = $(this).index(), deg; switch ( index ) { case 0: uploader.removeFile( file ); return; case 1: file.rotation += 90; break; case 2: file.rotation -= 90; break; } if ( supportTransition ) { deg = 'rotate(' + file.rotation + 'deg)'; $wrap.css({ '-webkit-transform': deg, '-mos-transform': deg, '-o-transform': deg, 'transform': deg }); } else { $wrap.css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')'); } }); $li.appendTo( $queue ); } // 負責view的銷燬 function removeFile( file ) { var $li = $('#'+file.id); delete percentages[ file.id ]; updateTotalProgress(); $li.off().find('.file-panel').off().end().remove(); } function updateTotalProgress() { var loaded = 0, total = 0, spans = $progress.children(), percent; $.each( percentages, function( k, v ) { total += v[ 0 ]; loaded += v[ 0 ] * v[ 1 ]; } ); percent = total ? loaded / total : 0; spans.eq( 0 ).text( Math.round( percent * 100 ) + '%' ); spans.eq( 1 ).css( 'width', Math.round( percent * 100 ) + '%' ); updateStatus(); } function updateStatus() { var text = '', stats; if ( state === 'ready' ) { text = '選中' + fileCount + '張Logo,共' + WebUploader.formatSize( fileSize ) + '。'; } else if ( state === 'confirm' ) { stats = uploader.getStats(); if ( stats.uploadFailNum ) { text = '已成功上傳' + stats.successNum+ '張Logo,'+ stats.uploadFailNum + '張Logo上傳失敗,<a class="retry" href="#">重新上傳</a>失敗Logo或<a class="ignore" href="#">忽略</a>' } } else { stats = uploader.getStats(); text = '共' + fileCount + '張(' + WebUploader.formatSize( fileSize ) + '),已上傳' + stats.successNum + '張'; if ( stats.uploadFailNum ) { text += ',失敗' + stats.uploadFailNum + '張'; } } $info.html( text ); } function setState( val ) { var file, stats; if ( val === state ) { return; } $upload.removeClass( 'state-' + state ); $upload.addClass( 'state-' + val ); state = val; switch ( state ) { case 'pedding': $placeHolder.removeClass( 'element-invisible' ); $queue.hide(); $statusBar.addClass( 'element-invisible' ); uploader.refresh(); break; case 'ready': $placeHolder.addClass( 'element-invisible' ); $( '#filePicker2' ).removeClass( 'element-invisible'); $queue.show(); $statusBar.removeClass('element-invisible'); uploader.refresh(); break; case 'uploading': $( '#filePicker2' ).addClass( 'element-invisible' ); $progress.show(); $upload.text( '暫停上傳' ); break; case 'paused': $progress.show(); $upload.text( '繼續上傳' ); break; case 'confirm': $progress.hide(); $( '#filePicker2' ).removeClass( 'element-invisible' ); $upload.text( '開始上傳' ); stats = uploader.getStats(); if ( stats.successNum && !stats.uploadFailNum ) { setState( 'finish' ); return; } break; case 'finish': stats = uploader.getStats(); if ( stats.successNum ) { alert( '上傳成功' ); } else { // 沒有成功的圖片,重設 state = 'done'; location.reload(); } break; } updateStatus(); } uploader.onUploadProgress = function( file, percentage ) { var $li = $('#'+file.id), $percent = $li.find('.progress span'); $percent.css( 'width', percentage * 100 + '%' ); percentages[ file.id ][ 1 ] = percentage; updateTotalProgress(); }; uploader.onFileQueued = function( file ) { fileCount++; fileSize += file.size; if ( fileCount === 1 ) { $placeHolder.addClass( 'element-invisible' ); $statusBar.show(); } addFile( file ); setState( 'ready' ); updateTotalProgress(); }; uploader.onFileDequeued = function( file ) { fileCount--; fileSize -= file.size; if ( !fileCount ) { setState( 'pedding' ); } removeFile( file ); updateTotalProgress(); }; uploader.on( 'all', function( type ) { var stats; switch( type ) { case 'uploadFinished': setState( 'confirm' ); break; case 'startUpload': setState( 'uploading' ); break; case 'stopUpload': setState( 'paused' ); break; } }); uploader.onError = function( code ) { alert( 'Eroor: ' + code ); }; $upload.on('click', function() { if ( $(this).hasClass( 'disabled' ) ) { return false; } if ( state === 'ready' ) { uploader.upload(); } else if ( state === 'paused' ) { uploader.upload(); } else if ( state === 'uploading' ) { uploader.stop(); } }); $info.on( 'click', '.retry', function() { uploader.retry(); } ); $info.on( 'click', '.ignore', function() { alert( 'todo' ); } ); $upload.addClass( 'state-' + state ); updateTotalProgress(); }); })( jQuery );
三、後端
1、web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>MultipartFileTest</display-name> <!-- 定義Spring MVC的前端控制器 --> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/springmvc-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <!-- 讓Spring MVC的前端控制器攔截所有請求 --> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <!-- 編碼過濾器 --> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
2、springmvc-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!-- spring可以自動去掃描base-pack下面的包或者子包下面的java檔案,
如果掃描到有Spring的相關注解的類,則把這些類註冊為Spring的bean -->
<context:component-scan base-package="cn.edu.jseti.controller"/>
<!-- 檢視解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 字首 -->
<property name="prefix">
<value>/WEB-INF/content/</value>
</property>
<!-- 字尾 -->
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!-- 上傳檔案大小上限,單位為位元組(10MB) -->
<property name="maxUploadSize">
<value>10485760</value>
</property>
<!-- 請求的編碼格式,必須和jSP的pageEncoding屬性一致,以便正確讀取表單的內容,預設為ISO-8859-1 -->
<property name="defaultEncoding">
<value>UTF-8</value>
</property>
</bean>
<!-- 開啟註解 -->
<mvc:annotation-driven />
<mvc:resources location="/js/" mapping="/js/**"/>
<mvc:resources location="/css/" mapping="/css/**"/>
<mvc:resources location="/images/" mapping="/images/**"/>
</beans>
3、FileUploadController.java
@Controller
public class FileUploadController {
@RequestMapping(value="/{formName}")
public String loginForm(@PathVariable String formName) {
// 動態跳轉頁面
return formName;
}
//上傳檔案會自動繫結到MultipartFile中
@RequestMapping(value="/upload",method=RequestMethod.POST)
public String upload(HttpServletRequest request,
@RequestParam("file") MultipartFile file) throws Exception {
//如果檔案不為空,寫入上傳路徑
if(!file.isEmpty()) {
//上傳檔案路徑
String path = request.getServletContext().getRealPath("/loaded/");
System.out.println("路徑:"+path);
//上傳檔名
String filename = file.getOriginalFilename();
System.out.println("檔名稱:"+filename);
File filepath = new File(path,filename);
//判斷路徑是否存在,如果不存在就建立一個
if (!filepath.getParentFile().exists()) {
filepath.getParentFile().mkdirs();
}
//將上傳檔案儲存到一個目標檔案當中
file.transferTo(new File(path + File.separator + filename));
return "success";
}
return null;
}
}
4、原始碼
相關推薦
webuploader結合SpringMVC實現多圖片上傳(附原始碼)
本案例實現多圖片上傳並且可以在前端預覽圖片,後端使用SpringMVC框架接收檔案,文章最後附原始碼。 一、效果 ![這裡寫圖片描述](https://img-blog.csdn.net/2018082816114114?watermark/2/text/aH
webuploader+springmvc實現多檔案上傳(html+js+css原創,後臺程式碼借鑑)
———————-css—————————- /*新增圖片按鈕*/ .add_resume_item { cursor: pointer; } /*遮罩層*/ .zpzs_gray { position: fixed; left: 0; to
TP5.0整合webuploader實現多圖片上傳功能
//**其實這一段js就是upload.js粘過來的,改成自己的路徑** var imgurl = new Array();//這個是自己新增的,用於把多張圖片的路徑放到這個jQuery陣列中然後賦值到表單提交 (function( $ ){ // 當domReady的時候開始
前端H5實現多圖片上傳並預覽
多檔案上傳並預覽 利用input 的type='file" 可以實現檔案的上傳,不過只支援單個檔案上傳。只有給input加上multiple屬性才能實現多個檔案同時上傳。 好了,下面我們來實現一個簡單的多圖片上傳並預覽的例子 <div class="input-file-box
Jfinal框架下結合ajaxFileupload實現多檔案上傳
距離寫程式碼時間有點長了,沒有及時總結,現在忘得差不多了。不過大概思路還在,也是有點參考價值的! 思路: 由於jfinal框架自身的問題,在實現多檔案上傳時很難獲取所有檔案的名字,只能獲取到一個input標籤裡面的名字而已,重寫框架是最佳的方法,但是對於初學者而言十分艱
KindEditor實現多圖片上傳
KindEditor的檔案上傳外掛:KindEditor 4.x 文件具體實現步驟demo:1.建立demo.jsp檔案,引入kindeditor的js檔案等,定義上傳檔案按鈕,這是一個div片段。<%@ page language="java" contentType
前端實現多圖片上傳檢視功能(帶UI實現)
由於業務需求,需要實現多圖片的上傳,並且能夠實時檢視使用者上傳的圖片列表。因此從網上找了一個不錯的外掛,並和bootstrap UI進行的相容。基本能夠滿足需求。下面就是我的實現過程(PS:本人前端了解不太深,所以基本是實現了功能… UI沒有太多考慮…)
Rxjava+Retrofit實現多圖片上傳
1、前言 專案需求:要求實現多張圖片上傳,並攜帶其他屬性值。 專案使用框架:Rxjava+Retrofit+Okhttp。 先附上大神寫的關於Retrofit的詳細用法,本文所寫以此文為基礎:Retrofit詳解。 2、後臺介面 分析後臺介
使用ueditor實現多圖片上傳案例——Dao層(BaseDao)
package org.dao; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet
利用FileReader實現多圖片上傳瀏覽重點記錄
FileReader用Base64對檔案流進行編碼var files = document.getElementById("file").files; if (files.length < 5) { for (var i = 0; i <
Asp.Net Core 2.1 WebAPI 通過IFormFileCollection實現多圖片上傳
背景 最近在學習 ASP.Net Core 2.1 WebAPI, 在做一個基於 Xamarin.Forms 3.1 App和 WebAPI 後端的小專案,其中有個功能要從手機端選擇多張圖片並且上傳到部署在Azure App Service上的Web
js實現多圖片上傳的預覽功能
圖片預覽: html程式碼: <input type="file" name="file" id="doc" multiple="multiple" style="width:150px;" onchange="javascript:setImagePrevi
freemarker+springMVC+ajaxfileupload實現非同步圖片上傳(單張)
第一步:下載JQuery的JS檔案ajaxfileupload.js 並引入到freemarker 第二步:freemarker頁面 <span style="font-size:18px;"><!DOCTYPE html> <html l
接口自動化實現圖片上傳(selenium/RF)
herf ict 上傳圖片 帶圖片 amp 怎麽 top .get imp 最近做自動化碰到一個問題: 就是帶圖片上傳的不知道怎麽實現自動化:整理了下實現如下: 上傳圖片postman 結果請求如下,上傳圖片後返回一個圖片地址: post請求 body 是form-da
如何抓取你所看到的網頁中的js特效(如:多圖片上傳的js特效)
首先在谷歌瀏覽器中搜索你想要的js特效(如:多圖片上傳功能的js特效),找到之後開啟對應的頁碼,按F12開啟除錯介面,如下:找到除錯介面的Source選項,然後對應的Network --> iframe,然後開啟下面的原始碼檔案,如圖片:img選項為:在圖片上點選右鍵的
jquery實現的ajax多圖上傳(移動端)
用thinkphp實現上傳的過程中碰到個很詭異的問題,一次傳6張圖片死活都不成功,折騰N久未果之後改為一次傳一張,但是使用者體驗太差,連續點6次是個人都得煩,而且無法保證使用者會乖乖的把六張圖都傳完。 後來瞭解到jquery可以輕鬆地實現ajax上傳,於是有了如下程式碼,僅
微信小程式圖片上傳(開發例項)
html部分 <!-- 圖片上傳 --> <view class='uploadimg'> <view class='uploadimgBox'> <block wx:for="{{imgs}}"
ASP.NET MVC 批量圖片上傳(縮圖)
HttpFileCollectionBase files = Request.Files; //宣告一個string儲存圖片路徑 //StringBuilder imgs = new
struts2.x多檔案上傳(使用註解)
一般網站都會提供檔案的上傳與下載的功能,尤其是資料管理型網站。剛好在工作中需要用到,就提前學習了一下,並建了一個maven工程做練習。 1. 本工程使用maven建立工程,是為了省去包匯入細節,其中maven工程的pom.xml檔案主要如下: <!--
Spring MVC 4使用Servlet 3 MultiPartConfigElement實現檔案上傳(帶原始碼)
package com.websystique.springmvc.controller; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; impor