最近的一个项目中,需要用到一个多文件上传,项目组长推荐了一个 jQuery Multiple File Upload Plugin ( http://www.fyneworks.com/jquery/multiple-file-upload/ )让我调研一下,简单研究了一下,感觉还不错,就拿出来晒晒。
首先我这里因为项目中使用的是 SpringMVC ,所以这边后台我就直接使用 Spring 中的 MultipartFile 中进行处理。
我们在 multifile 中可以很容易的发现如何使用,这里就简单说说了,首先在页面上我们需要有这样几行标签代码
<!-- 注意这里的attach名字为固定,如果要控制上传的格式,则追加accept="doc|txt|jsp" 最大上传量maxlength="3" --> <input type="file" name="attach" id="multiFileId" class=" input_txt"/> <div id="multiFileId-list"></div>
然后在该页面中引入相关的JS和CSS
<script src="./js/multifile/jquery.MetaData.js" type="text/javascript"></script> <script src="./js/multifile/jquery.MultiFile.js" type="text/javascript"></script> <script src="./js/multifile/jquery.blockUI.js" type="text/javascript"></script> <script src="./js/multifile/documentation.js" type="text/javascript"></script> <link href="./js/multifile/documentation.css" type="text/css" rel="stylesheet" />
然后通过js和设置刚刚写入的标签
<script type="text/javascript"> $(function() { //加载多文件上传的JS $('#multiFileId').MultiFile( { list : '#multiFileId-list', STRING : { remove : '<img src="http://www.fyneworks.com/i/bin.gif" height="16" width="16" alt="x"/>' } }); }); </script>
当然,上面的这段 JS 以及上面的 HTML 标签,我们可以根据实际的情况参考官网上的 Demo 上说明的属性进行设置。
Ok ,前台我们使用这个插件的地方基本就 ok 了,下面我们需要关心的是后台我们如何处理这里上传的多文件进行保存。在调研的过程中我将这一部分简单的写了一个工具类。
首先在 Controller 里接收
@RequestMapping(value="/uploadFile/upload.ac", method = RequestMethod.POST) public String uploadFile(HttpServletRequest request, HttpServletResponse response) { List<MultipartFile> multipartFiles = UploadHelper.getFileSet(request, 1024 * 20, null); String path = "D:" + File.separator; if (multipartFiles.size() == 0) { // TODO 给出提示,不允许没选择文件点击上传 } for (MultipartFile multipartFile : multipartFiles) { try { String filePath = UploadHelper.uploadFile(multipartFile, path); System.out.println(filePath); } catch (Exception e) { e.printStackTrace(); } // 拿到的imgPath就是图片的相对于contextPath的存储路径了 } return null; }
UploadHelper.java
package org.elongcom.common; import java.io.File; import java.util.Arrays; import java.util.LinkedList; import java.util.List; import java.util.UUID; import javax.servlet.http.HttpServletRequest; import org.springframework.util.FileCopyUtils; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; /** * @author xdwang * * @create 2012-11-19 下午6:24:03 * * @email:[email protected] * * @description 上传帮助类 * */ public class UploadHelper { /** * @descrption 根据HttpServletRequest对象获取MultipartFile集合 * @author xdwang * @create 2012-11-19下午5:11:41 * @param request * @param maxLength * 文件最大限制 * @param allowExtName * 不允许上传的文件扩展名 * @return MultipartFile集合 */ public static List<MultipartFile> getFileSet(HttpServletRequest request, long maxLength, String[] allowExtName) { MultipartHttpServletRequest multipartRequest = null; try { multipartRequest = (MultipartHttpServletRequest) request; } catch (Exception e) { return new LinkedList<MultipartFile>(); } List<MultipartFile> files = new LinkedList<MultipartFile>(); files = multipartRequest.getFiles("attach"); // 移除不符合条件的 for (int i = 0; i < files.size(); i++) { if (!validateFile(files.get(i), maxLength, allowExtName)) { files.remove(files.get(i)); if (files.size() == 0) { return files; } } } return files; } /** * @descrption 保存文件 * @author xdwang * @create 2012-11-19下午4:17:36 * @param file * MultipartFile对象 * @param path * 保存路径,如“D:\\File\\” * @return 保存的全路径 如“D:\\File\\2345678.txt” * @throws Exception * 文件保存失败 */ public static String uploadFile(MultipartFile file, String path) throws Exception { String filename = file.getOriginalFilename(); String extName = filename.substring(filename.lastIndexOf(".")) .toLowerCase(); String lastFileName = UUID.randomUUID().toString() + extName; if (!path.endsWith(File.separator)) { path = path + File.separator; } File temp = new File(path); if (!temp.isDirectory()) { temp.mkdir(); } // 图片存储的全路径 String fileFullPath = path + lastFileName; FileCopyUtils.copy(file.getBytes(), new File(fileFullPath)); return fileFullPath; } /** * @descrption 验证文件格式,这里主要验证后缀名 * @author xdwang * @create 2012-11-19下午4:08:12 * @param file * MultipartFile对象 * @param maxLength * 文件最大限制 * @param allowExtName * 不允许上传的文件扩展名 * @return 文件格式是否合法 */ private static boolean validateFile(MultipartFile file, long maxLength, String[] allowExtName) { if (file.getSize() < 0 || file.getSize() > maxLength) return false; String filename = file.getOriginalFilename(); // 处理不选择文件点击上传时,也会有MultipartFile对象,在此进行过滤 if (filename == "") { return false; } String extName = filename.substring(filename.lastIndexOf(".")) .toLowerCase(); if (allowExtName == null || allowExtName.length == 0 || Arrays.binarySearch(allowExtName, extName) != -1) { return true; } else { return false; } } }
这里需要多说一点的是,表单提交时如果有文件进行上传时,需要在表单上设置enctype="multipart/form-data",否则上面的 multipartRequest = (MultipartHttpServletRequest) request;进行强转时会报错。
Ok,收工。