Bootstrap框架---Uploadify插件----多张图片上传交互方式二
我们在前一章已经实现了Bootstrap框架---Uploadify插件----多张图片上传交互方式一 。 Bootstrap框架---Uploadify插件----多张图片上传交互方式一 本章主要关注多张(动态张数)图片上传在Bootstrap框架中的布局和实现。 我们在之前的文章中已经在SpringMVC基础框架的基础上应用了BootStrap的后台框架,在此基础上记录?多张图片上传在Bootstrap框架中的布局方式二和实现。 基础项目源码下载地址为: SpringMVC+Shiro+MongoDB+BootStrap基础框架 我们在基础项目中已经做好了首页index的访问。 效果图实现思路是动态的初始化上传组件,需要多少张图片则初始化多少个组件。后台用List接收图片。 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版是收费的,在网上找到一个直接可用html5版本的JS。
下载地址:
uploadifyHtml5
下载解压后放到项目路径中
这里还需要一张样式图片,我们放在/res/assets/img/demoUpload.jpg路径。
JSP页面<%@ include file="./include/header.jsp"%> <%@ taglib uri="com.data.web.view.function" prefix="cf" %> <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="base"> ? ? ? ? ? ? ? ? ?<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 class="col-sm-2 control-label"> 图片 </label> ? ? ? ? ? ? ? ? ? ? <div class="col-sm-10"> ? ? ? ? ? ? ? ? ? ? ? ? <table id="imagePaths" class="table table-striped table-bordered" cellspacing="0" ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?style="margin-bottom: 0;"> ? ? ? ? ? ? ? ? ? ? ? ? ? ? <thead> ? ? ? ? ? ? ? ? ? ? ? ? ? ? <tr> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <th width="25%" class="text-center">标题</th> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <th width="*" class="text-center">图片地址</th> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <th width="25%" class="text-center">描述</th> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <th width="15%" class="text-center">操作</th> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <th width="15%"></th> ? ? ? ? ? ? ? ? ? ? ? ? ? ? </tr> ? ? ? ? ? ? ? ? ? ? ? ? ? ? </thead> ? ? ? ? ? ? ? ? ? ? ? ? ? ? <tbody> ? ? ? ? ? ? ? ? ? ? ? ? ? ? </tbody> ? ? ? ? ? ? ? ? ? ? ? ? </table> ? ? ? ? ? ? ? ? ? ? ? ? <script type="text/template" id="tpl_imagePaths"> ? ? ? ? ? ? ? ? ? ? ? ? ? ? <tr> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <td><input type="text" class="form-control" value="{title}" name="title"></td> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <td><input type="text" class="form-control" value="{filePath}" name="filePath" ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?id="video_{rowIndx}_filePath"></td> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <td><input type="text" class="form-control" value="{description}" name="description"> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </td> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <td> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <button type="button" class="btn btn-danger imgUploader" ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? id="video_{rowIndx}_uploader" style="width:120px;height:30px;">图片上传 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </button> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </td> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <td class="text-center"> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <button type="button" class="btn btn-default btn-sm row-add" title="添加行"><i ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? class="fa fa-plus fa-fw"></i></button> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? <button type="button" class="btn btn-default btn-sm row-del" title="删除行"><i ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? class="fa fa-minus fa-fw"></i></button> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? </td> ? ? ? ? ? ? ? ? ? ? ? ? ? ? </tr> ? ? ? ? ? ? ? ? ? ? ? ? </script> ? ? ? ? ? ? ? ? ? ? </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"> /** ?* 格式化字符串 第一个参数为格式化模板 format('this is a {0} template!','format'); ?* format('this is a {0.message} template!',{ message: 'format'}); 等同于 ?* format('this is a {message} template!',{ message: 'format' }); ?*/ $.format = function() { var template = arguments[0],? templateArgs = arguments,? stringify = function(obj) { ? ? if (obj == null) { ? ? ? return ''; ? ? } else if (typeof obj === 'function') { ? ? ? return obj(); ? ? } else if (typeof obj !== 'string') { ? ? ? return JSON.stringify ? JSON.stringify(obj) : obj; ? ? } ? ? return obj; ? }; return template.replace(/{w+(.w+)*}/g,function(match) { ? var propChains = match.slice(1,-1).split('.'); ? var index = isNaN(propChains[0]) ? 0 : +propChains.shift(); ? var arg,prop; ? if (index + 1 < templateArgs.length) { ? ? arg = templateArgs[index + 1]; ? ? while (prop = propChains.shift()) { ? ? ? arg = arg[prop] == null ? '' : arg[prop]; ? ? } ? ? return stringify(arg); ? } ? return match; }); }; /** ?* jQuery form 扩展绑定数据 ?*? ?*/ $.fn.formSet = function(data,formGroup) { var els = formGroup ? this.find('[form-group="' + formGroup + '"]') : this.find('[name]'); if (!els || !els.length) { ? return this; } els.each(function() { ? var $this = $(this),? ? type = $this.attr('type'),? ? name = $this.attr('name'),? ? tag = this.tagName.toLowerCase(); ? var value = _fnObjectGetPropertyChainValue(data,name); ? if (tag == 'input') { ? ? if (type == 'checkbox') { ? ? ? var v = $(this).val(); ? ? ? if (v == 'on' || !v) { ? ? ? ? this.checked = value ? 'checked' : ''; ? ? ? } else { ? ? ? ? this.checked = $.isArray(value) && value.indexOf(v) > -1 ? 'checked' : '' ? ? ? } ? ? } else if (type == 'radio') { ? ? ? this.checked = $this.val() == String(value) ? 'checked' : ''; ? ? } else { ? ? ? $this.val(value); ? ? } ? } else if ('|select|textarea|'.indexOf('|' + tag + '|') > -1) { ? ? $this.val(value); ? } else { ? ? $this.html(value); ? } }); return this; }; /** ?* jQuery form 扩展获取数据 ?*/ $.fn.formGet = function(opts) { opts = $.extend({},opts); var data = {},? els = opts.formGroup ? this.find('[form-group="' + opts.formGroup + '"]') : this.find('[name]'); if (!els || !els.length) { ? return data; } var fnSetValue = (function(emptyToNull) { ? return emptyToNull ? function(obj,propertyChain,value,allowMulti) { ? ? value !== '' && _fnObjectSetPropertyChainValue(obj,allowMulti) ? } : _fnObjectSetPropertyChainValue })(opts.emptyToNull); els.each(function() { ? var $this = $(this),// 可能为属性链 ? ? tag = this.tagName.toLowerCase(); ? if (tag == 'input') { ? ? if (type == 'checkbox') { ? ? ? var v = $(this).val(); ? ? ? if (v == 'on' || !v) { ? ? ? ? fnSetValue(data,name,$(this).prop('checked')); ? ? ? } else { ? ? ? ? $(this).prop('checked') && fnSetValue(data,v,true); ? ? ? } ? ? } else if (type == 'radio') { ? ? ? this.checked && fnSetValue(data,$this.val()); ? ? } else { ? ? ? fnSetValue(data,$this.val()); ? ? } ? } else if ('|select|textarea|'.indexOf('|' + tag + '|') > -1) { ? ? fnSetValue(data,$this.val()); ? } else { ? ? fnSetValue(data,$.trim($this.text())); ? } }); return data; }; /** ?* 内部私有方法 ?*/ var _fnObjectGetPropertyChainValue = function(obj,propertyChain) { ? /* 获取属性链的值 */ ? if (!obj) return; ? if (!propertyChain) return obj; ? var property,? ? chains = propertyChain.split('.'),? ? i = 0,? ? len = chains.length; ? for (; ? ? (property = chains[i]) && i < len - 1; i++) { ? ? if (!obj[property]) return; ? ? obj = obj[property]; ? } ? return obj[property]; },_fnObjectSetPropertyChainValue = function(obj,allowMulti) { ? /* 设置属性链的值 */ ? if (!obj || !propertyChain) return; ? var property,? ? chainObj = obj,? ? len = chains.length; ? for (; ? ? (property = chains[i]) && i < len - 1; i++) { ? ? if (!chainObj[property]) { ? ? ? chainObj[property] = {}; ? ? } ? ? chainObj = chainObj[property]; ? } ? // 改进版:checkbox的多选可以组合为数组 ? if (!allowMulti || chainObj[property] === undefined) { ? ? chainObj[property] = value; ? } else { ? ? var pv = chainObj[property]; ? ? if ($.isArray(pv)) { ? ? ? pv.push(value); ? ? } else { ? ? ? chainObj[property] = [pv,value]; ? ? } ? } ? return obj; }; ?? ? ? $(document).ready(function () { ? ? /*BEGIN-图片-BEGIN*/ ? ? ? ? var $imagePathsBody = $('#imagePaths tbody'),? ? ? ? ? ? _imagePathsTpl = $('#tpl_imagePaths').html(); ? ? ? ? // 初始化图片列表 ? ? ? ? (function (imges) { ? ? ? ? ? ? if (!imges) { ? ? ? ? ? ? ? ? imges = [{}]; ? ? ? ? ? ? } ? ? ? ? ? ? for (var i = 0,item; item = imges[i]; i++) { ? ? ? ? ? ? ? ? $imagePathsBody.append($($.format(_imagePathsTpl,{rowIndx: i})).formSet(item)); ? ? ? ? ? ? } ? ? ? ? })(${cf:toJSON(base.imagePaths)} ? ? ? ? ); ? ? ? ? function _getImagePaths() { ? ? ? ? ? ? var imges = []; ? ? ? ? ? ? $imagePathsBody.find('tr').each(function (index,ele) { ? ? ? ? ? ? ? ? var row = $(ele).formGet(); ? ? ? ? ? ? ? ? if (row.title || row.filePath || row.duration) { ? ? ? ? ? ? ? ? ? ? imges.push({"title": row.title,"filePath": row.filePath,"description": row.description}); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? }); ? ? ? ? ? ? return imges; ? ? ? ? }; ? ? ? ? $imagePathsBody.on('click','.row-del',function () { ? ? ? ? ? ? var $tr = $(this).closest('tr'); ? ? ? ? ? ? if ($tr.parent().children().length == 1) return; ? ? ? ? ? ? $tr.remove(); ? ? ? ? }).on('click','.row-add',function () { ? ? ? ? ? ? var $tr = $(this).closest('tr'); ? ? ? ? ? ? $imagePathsBody.append($($.format(_imagePathsTpl,{rowIndx: $tr.parent().children().length})).formSet({})); ? ? ? ? ? ? initUploader(); ? ? ? ? }); ? ? ? ? /*END-图片-END*/ ? ? ? ? /* BEGIN-图片上传-BEGIN */ ? ? ? ? var initUploader = function () { ? ? ? ? ? ? $('.imgUploader').each(function (index) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? var selfId = this.id; ? ? ? ? ? ? ? ? var $input = $('#' + selfId.replace('_uploader','_filePath')); ? ? ? ? ? ? ? ? console.log($input); ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ? var $uploader = $('#uploadifive-video_' +index+'_uploader' ); ? ? ? ? ? ? ? ? if(!($uploader.length>0)){ ? ? ? ? ? ? ? ? $(this).uploadifive({ ? ? ? ? ? ? ? ? ? ? 'height': 30,? ? ? ? ? ? ? ? ? ? 'width': 120,? ? ? ? ? ? ? ? ? ? 'fileSizeLimit': '500KB',? ? ? ? ? ? ? ? ? ? 'uploadScript': '/upload;_sid=${pageContext.session.id}',? ? ? ? ? ? ? ? ? ? 'buttonClass': 'btn btn-danger',? ? ? ? ? ? ? ? ? ? 'buttonText': '图片上传',? ? ? ? ? ? ? ? ? ? 'multi': false,? ? ? ? ? ? ? ? ? ? 'removeCompleted': true,? ? ? ? ? ? ? ? ? ? 'onUploadComplete': function (file,data,response) { ? ? ? ? ? ? ? ? ? ? ? ? data = JSON.parse(data); ? ? ? ? ? ? ? ? ? ? ? ? if (data.code) { ? ? ? ? ? ? ? ? ? ? ? ? ? ? var url = '${hostname}' + data.result; ? ? ? ? ? ? ? ? ? ? ? ? ? ? $input.val(url).change(); ? ? ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? }); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? ? ?? ? ? ? ? ? ? }); ? ? ? ? }; ? ? ? ? initUploader(); ? ? ? ? //图片容器的显示图片切换 ? ? ? ? var updateUploadButtonBackground = function (id,path) { ? ? ? ? ? ? path ? $('#uploadifive-' + id).css('background-image','url(' + path + ')') : $('#uploadifive-' + id).css('background-image','url(/res/assets/img/demoUpload.jpg)'); ? ? ? ? }; ? ? ? ? //删除图片 ? ? ? ? ? ? $('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(''); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? }); ? ? ? ?? ? ? ? ?? ? ? ? ? /*END-图片上传-END*/ ? ? ? ? $('button.save').on('click',function () { ? ? ? ? ? ? debugger; ? ? ? ? ? ? var data = $('#base').formGet(); ? ? ? ? ? ? if (_getImagePaths().length) ? ? ? ? ? ? ? ? data.imagePaths = _getImagePaths(); ? ? ? ? ? ? $.ajax({ ? ? ? ? ? ? ? ? type: "POST",? ? ? ? ? ? ? ? url: "/pic/save",? ? ? ? ? ? ? ? contentType: "application/json",? ? ? ? ? ? ? ? data: JSON.stringify(data),? ? ? ? ? ? ? ? success: function (result) { ? ? ? ? ? ? ? ? ? ? console.log(result); ? ? ? ? ? ? ? ? ? ? if (!result.code) { ? ? ? ? ? ? ? ? ? ? ? ? $('#base').formSet(data); ? ? ? ? ? ? ? ? ? ? } else { ? ? ? ? ? ? ? ? ? ? ? ? alert(result.msg); ? ? ? ? ? ? ? ? ? ? } ? ? ? ? ? ? ? ? },? ? ? ? ? ? ? ? error: function (result) { ? ? ? ? ? ? ? ? ? ? alert("出错了,请稍后重试"); ? ? ? ? ? ? ? ? } ? ? ? ? ? ? }); ? ? ? ? }); ? ? ? ? ? ? }); </script> </body> </html> 返回信息辅助实体类AjaxResult.javapackage com.test.util; import org.springframework.data.annotation.Transient; /** * AjaxResult * * 标准化的ajax响应,取代之前直接返回结果的方式。 * */ public class AjaxResult { @Transient public static final int CODE_SUCCESS = 1; @Transient public static final int CODE_FAILURE = 0; @Transient public static final AjaxResult RESULT_ERROR = new AjaxResult( CODE_FAILURE,"执行出错了",null); @Transient public static final AjaxResult RESULT_SUCCESS = new AjaxResult( CODE_SUCCESS,null,null); @Transient public 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,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.javapackage 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); private int code; private String msg; private Object data; /** * 创建一个成功的响应 * * @param data * @return */ public static JSONResult success(Object data) { return new JSONResult(CODE_SUCCESS,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.javapackage com.test.domain.entity; import java.util.List; public class Pic { private String id; private String name; private String description; private List<Image> imagePaths; // 图片 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 List<Image> getImagePaths() { return imagePaths; } public void setImagePaths(List<Image> imagePaths) { this.imagePaths = imagePaths; } } 页面路由控制器IndexController.javapackage 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") @ResponseBody public JSONResult saveMigrateLine(@RequestBody Pic pic) { //保存pic记录 //int result = save(pic); int result =1; return result > 0 ? JSONResult.success(pic) :JSONResult.error("保存失败!"); } } 文件上传接收控制器UploadController.javapackage 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") @ResponseBody public 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,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页面把图片显示去掉即可。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |