Bootstrap框架---Uploadify插件----多张图片上传交互方式一
我們在前一章已經實現了Bootstrap框架---Uploadify插件----單張圖片上傳。
Bootstrap框架----單張圖片上傳實現---Uploadify插件
本章實現Bootstrap框架---Uploadify插件----多張圖片上傳交互方式一 。
本章主要關注多張圖片上傳在Bootstrap框架中的布局和實現。
我們在之前的文章中已經在SpringMVC基礎框架的基礎上應用了BootStrap的后臺框架,在此基礎上記錄?多張圖片上傳在Bootstrap框架中的布局方式一和實現。
基礎項目源碼下載地址為:
SpringMVC+Shiro+MongoDB+BootStrap基礎框架
我們在基礎項目中已經做好了首頁index的訪問。
現在就在index.jsp頁面和index的路由Controller上做修改,實現 ?多張圖片上傳在Bootstrap框架中的布局和實現。
效果圖
實現思路是平行的初始化Uploadify,比如要上傳2張,就初始化出2個上傳組件。
這里的話只支持少量固定多張圖片上傳,比如一個實體中有2到3個圖片字段時。
Uploadify插件介紹
Uploadify是jQuery的一個上傳插件,主要功能是批量上傳文件,實現的效果非常不錯,帶進度顯示。而且是Ajax的,省去了自己寫Ajax上傳功能的麻煩。不過官方提供的實例是PHP版本的,本文將詳細介紹Uploadify在J2EE中的使用。
Uploadify的官網鏈接:http://www.uploadify.com/?
里面可以看到PHP的示例,屬性說明,以及控件下載地址。
分flash版(免費)和HTML5版(收費)。
官網上可以看到效果演示。
需要注意的是flash版在Safari不支持。
會報錯:
Uploadify Flash Safari wrong JSESSIONID
HTML5版是收費的,在網上找到一個直接可用html5版本的JS。
下載地址:
uploadifyHtml5
下載解壓后放到項目路徑中
這里還需要一張樣式圖片,我們放在/res/assets/img/demoUpload.jpg路徑。
JSP頁面
<%@ include file="./include/header.jsp"%> <style> /*uploadfive上傳插件背景按鈕圖樣式*/ .upload-image {height: 200px;width: 200px;background-image: url(/res/assets/img/demoUpload.jpg);background-color: white;background-repeat: no-repeat;background-size: contain;background-origin: content-box;background-position: center;background-size: contain;background-origin: content-box; } </style><div id="page-wrapper"><div id="page-inner"><div class="row"><div class="col-md-12"><h1 class="page-header">多(兩)張圖片上傳 <small>Uploadify</small></h1></div></div><!-- /. ROW ?--><form class="form-horizontal" id="test"><input type="text" value="${pic.id}" id="id" name="id" hidden/><div class="form-group"><label for="name" class="col-sm-2 control-label">名稱:</label><div class="col-sm-10"><input type="text" class="form-control" id="name" name="name" value="${pic.name}"placeholder="路線名稱,例如:A-F"></div></div><div class="form-group"><label class="col-sm-2 control-label">描述:</label><div class="col-sm-10"><textarea id="description" name="description" class="form-control"rows="8">${pic.description}</textarea></div></div><div class="form-group"><label for="icon" class="col-sm-2 control-label">樹圖片</label><div class="col-sm-10"><input type="text" class="form-control" id="img_upload_filePath"value="${pic.img}" name="img" placeholder="圖片地址" readonlyref-selector=".ref-icon"/></div></div><c:if test="${pic.img!=null&&pic.img!=''}"><div class="form-group"><div class="col-sm-6 col-sm-offset-2"><button type="button" class="btn btn-danger ?delete"data-loading-text="刪除中..." id="img_upload_delete" id="img-del">刪除樹圖片</button></div></div></c:if><div class="form-group"><div class="col-sm-6 col-sm-offset-2"><imgsrc="${pic.img!=null&&pic.img!=''?pic.img:'/res/assets/img/demoUpload.jpg'}"id="img_upload_uploader" class="img-thumbnail img_upload_uploader"style="width:300px; height:300px;"></div></div><div class="form-group"><label for="icon" class="col-sm-2 control-label">全路線圖片</label><div class="col-sm-10"><input type="text" class="form-control" id="lineImg_upload_filePath"value="${pic.lineImg}" name="lineImg" placeholder="圖片地址" readonlyref-selector=".ref-icon"/></div></div><c:if test="${pic.lineImg!=null&&pic.lineImg!=''}"><div class="form-group"><div class="col-sm-6 col-sm-offset-2"><button type="button" class="btn btn-danger ?delete"data-loading-text="刪除中..." id="lineImg_upload_delete" id="img-del">刪除路線圖片</button></div></div></c:if><div class="form-group"><div class="col-sm-6 col-sm-offset-2"><imgsrc="${pic.lineImg!=null&&pic.lineImg!=''?pic.lineImg:'/res/assets/img/demoUpload.jpg'}"id="lineImg_upload_uploader" class="img-thumbnail lineImg_upload_uploader"style="width:300px; height:300px;"></div></div><div class="form-group"><div class="col-sm-6 col-sm-offset-2"><button type="button" class="btn btn-default cancel"data-dismiss="modal">取消</button><button type="button" class="btn btn-primary save"data-loading-text="Saving...">確認</button></div></div></form> ?<!-- /. ROW ?--></div><!-- /. PAGE INNER ?--></div><!-- /. PAGE WRAPPER ?--><%@ include file="./include/footer.jsp"%> <script type="text/javascript" src="/plugins/uploadify/jquery.uploadifive.js"></script> <script type="text/javascript">$(document).ready(function () { //圖片容器的顯示圖片切換var updateUploadButtonBackground = function (id, path) {path ? $('#uploadifive-' + id).css('background-image', 'url(' + path + ')') : $('#' + id + '-button').css('background-image', 'url(/res/assets/img/demoUpload.jpg)');};//初始化圖片上傳容器var initImageUploader = function () {$('.img_upload_uploader, .lineImg_upload_uploader').each(function () {var selfId = this.id;var $input = $('#' + selfId.replace('_uploader', '_filePath'));console.log($input);$(this).uploadifive({'height': 300,'width': 300,'uploadScript': '/upload;_sid=${pageContext.session.id}','fileSizeLimit': '1200KB','buttonClass': 'upload-image img-thumbnail','buttonText': '','multi': false,'onInit': function (instance) {updateUploadButtonBackground(selfId, $input.val());},'removeCompleted': true,'onUploadComplete': function (file, data, response) {data = JSON.parse(data);if (data.code) {var url = '${hostname}' + data.result;$input.val(url);updateUploadButtonBackground(selfId, url);}}});});};initImageUploader();//刪除圖片$('button.delete').on('click',function () {if (confirm('是否刪除圖片?')) {var selfId = this.id;var $input = $('#' + selfId.replace('_delete', '_filePath'));var uploaderId = selfId.replace('_delete', '_uploader');updateUploadButtonBackground(uploaderId, '/res/assets/img/demoUpload.jpg');$input.val('');}});$('button.save').on('click', function () {debugger;var data = $('#test').formGet();if (!data.name || (data.name.trim()).length == 0) {alert("名稱不能為空.");return false;}$.ajax({type: "POST",url: "/pic/save",contentType: "application/json",data: JSON.stringify(data),success: function (result) {console.log(result);if (!result.code) {$('#test').formSet(data);alert(result.msg);} else {alert(result.msg);}},error: function (result) {alert("出錯了,請稍后重試");}});});});</script></body></html>返回信息輔助實體類
AjaxResult.java
package com.test.util;import org.springframework.data.annotation.Transient;/*** AjaxResult* * 標準化的ajax響應, 取代之前直接返回結果的方式。* */ public class AjaxResult {@Transientpublic static final int CODE_SUCCESS = 1;@Transientpublic static final int CODE_FAILURE = 0;@Transientpublic static final AjaxResult RESULT_ERROR = new AjaxResult(CODE_FAILURE, "執行出錯了", null);@Transientpublic static final AjaxResult RESULT_SUCCESS = new AjaxResult(CODE_SUCCESS, null, null);@Transientpublic static final AjaxResult RESULT_INVAILD_PARAMETER = new AjaxResult(CODE_FAILURE, "參數格式不正確", null);private int code = CODE_FAILURE;private String error;private Object result;public static AjaxResult resultError(String error) {return new AjaxResult(CODE_FAILURE, error, null);}public static AjaxResult resultSuccess(Object result) {return new AjaxResult(CODE_SUCCESS, null, result);}/*** @param code* @param error* @param result*/public AjaxResult(int code, String error, Object result) {super();this.code = code;this.error = error;this.result = result;}/*** @return the code*/public int getCode() {return code;}/*** @param code* the code to set*/public void setCode(int code) {this.code = code;}/*** @return the error*/public String getError() {return error;}/*** @param error* the error to set*/public void setError(String error) {this.error = error;}/*** @return the result*/public Object getResult() {return result;}/*** @param result* the result to set*/public void setResult(Object result) {this.result = result;} }JSONResult.java
package com.test.util;/*** JSONResult* 標準化的JSON響應* * <pre>* {@link JSONResult#success(Object)}* {@link JSONResult#error(String)}* </pre>* * */ public class JSONResult {/*** 成功的代碼*/public static final int CODE_SUCCESS = 0;/*** 錯誤的代碼,可根據錯誤類型進行詳細分類*/public static final int CODE_ERROR = -1;/*** 空白的成功響應*/public static final JSONResult RESULT_SUCCESS_NO_DATA = new JSONResult(CODE_SUCCESS, null, null);private int code;private String msg;private Object data;/*** 創建一個成功的響應* * @param data* @return*/public static JSONResult success(Object data) {return new JSONResult(CODE_SUCCESS, null, data);}/*** 創建一個錯誤的響應* * @param msg* @return*/public static JSONResult error(String msg) {return new JSONResult(CODE_ERROR, msg, null);}/*** @param code* @param msg* @param data*/public JSONResult(int code, String msg, Object data) {this.code = code;this.setMsg(msg);this.data = data;}public int getCode() {return code;}public JSONResult setCode(int code) {this.code = code;return this;}public Object getData() {return data;}public JSONResult setData(Object data) {this.data = data;return this;}public String getMsg() {return msg;}public JSONResult setMsg(String msg) {this.msg = msg;return this;}}Pic.java
package com.test.domain.entity;public class Pic {private String id;private String name;private String description;private String img;private String lineImg;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getImg() {return img;}public void setImg(String img) {this.img = img;}public String getLineImg() {return lineImg;}public void setLineImg(String lineImg) {this.lineImg = lineImg;}}頁面路由控制器
IndexController.java
package com.test.web.controller;import java.io.IOException;import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import com.test.domain.entity.Pic; import com.test.util.JSONResult;/*** IndexController* * */ @Controller public class IndexController {@RequestMapping("/")public String index(Model model) throws IOException {model.addAttribute("hostname", "http://127.0.0.1:8080/");return "/index";}@RequestMapping("/pic/save")@ResponseBodypublic JSONResult saveMigrateLine(@RequestBody Pic pic) {//保存pic記錄//int result = save(pic);int result =1;return result > 0 ? JSONResult.success(pic):JSONResult.error("保存失敗!");} }文件上傳接收控制器
UploadController.java
package com.test.web.controller;import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.List;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;import com.test.util.AjaxResult;/*** 通用的上傳(保存到本地服務器)* */ @Controller public class UploadController {private final Logger logger = LoggerFactory.getLogger(getClass().getName());/*** 上傳到服務器,文件名稱隨機生成(基本可以保證不重復)* * @param request* @param response* @return AjaxResult 存儲的文件的相對路徑* @throws IOException */@RequestMapping("/upload")@ResponseBodypublic AjaxResult upload(HttpServletRequest request, HttpServletResponse response) throws IOException {try {String filePath="/uploadfile";//獲取文件存儲路徑 (虛擬目錄映射為本機服務器的實際目錄)String path = request.getSession().getServletContext().getRealPath(filePath); //如果保存在ROOT里,重新發包后靜態資源會丟失,所以保存在ROOT包的上級路徑webapp中path=path.replace("ROOT\\", "");String fileNameResult ="";// 判斷enctype屬性是否為multipart/form-data boolean isMultipart = ServletFileUpload.isMultipartContent(request); if (!isMultipart) throw new IllegalArgumentException( "上傳內容不是有效的multipart/form-data類型."); // Create a factory for disk-based file items DiskFileItemFactory factory = new DiskFileItemFactory(); // Create a new file upload handler ServletFileUpload upload = new ServletFileUpload(factory); // Parse the request List<?> items = upload.parseRequest(request); Iterator iter = items.iterator(); while (iter.hasNext()) { FileItem item = (FileItem) iter.next(); if (item.isFormField()) { // 如果是普通表單字段 String name = item.getFieldName(); String value = item.getString(); // ... } else { // 如果是文件字段 String fieldName = item.getFieldName(); String fileName = item.getName(); String contentType = item.getContentType(); boolean isInMemory = item.isInMemory(); long sizeInBytes = item.getSize(); String fileExt = fileName.substring(fileName.lastIndexOf('.'));String fileNameNew =getFileNameNew()+fileExt;fileNameResult=fileNameNew;//保存到本地InputStream uploadedStream = item.getInputStream(); savePic(path,uploadedStream,fileNameNew);uploadedStream.close(); } } return AjaxResult.resultSuccess(filePath+"/"+fileNameResult);} catch (FileUploadException e) {logger.warn(e.getMessage(), e);return AjaxResult.resultError(e.getMessage());}}private void savePic(String path,InputStream inputStream, String fileName) {OutputStream os = null;try {// 2、保存到臨時文件// 1K的數據緩沖byte[] bs = new byte[1024];// 讀取到的數據長度int len;// 輸出的文件流保存到本地文件File tempFile = new File(path);if (!tempFile.exists()) {tempFile.mkdirs();//如果圖片是保存在ROOT項目外,首次創建目錄,tomcat加載需要時間,所以需要延遲10秒Thread.sleep(10000);}os = new FileOutputStream(tempFile.getPath() + File.separator + fileName);// 開始讀取while ((len = inputStream.read(bs)) != -1) {os.write(bs, 0, len);}} catch (IOException e) {e.printStackTrace();} catch (Exception e) {e.printStackTrace();} finally {// 完畢,關閉所有鏈接try {os.close();inputStream.close();} catch (IOException e) {e.printStackTrace();}}}private String getFileNameNew() {SimpleDateFormat fmt = new SimpleDateFormat("yyyyMMddHHmmssSSS");return fmt.format(new Date());}}目前上傳的文件是接收后保存到本地服務器中,如果要上傳到遠程服務器或者七牛云等,只需要修改UploadController.java即可。
這里只給出了?uploadify 上傳圖片的案例。 但其實 這個DEMO也可以用于上傳 zip等文件。 只需要稍微調整jsp頁面把圖片顯示去掉即可。
總結
以上是生活随笔為你收集整理的Bootstrap框架---Uploadify插件----多张图片上传交互方式一的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 下载腾讯视频(mp4 格式)
- 下一篇: 金蝶K3 数据表知识整理(不断完善)