Uploadify是一种jQuery的上传插件,因为项目涉及到多文件上传,所以采用了这一插件。
项目使用了SpringBoot,前端采用的是EasyUI+Thymeleaf模板。
前端HTML代码:
1 <!DOCTYPE html> 2 <html xmlns:th="http://www.thymeleaf.org"> 3 <head> 4 <meta charset="UTF-8" /> 5 <title>文件上传</title> 6 7 <link rel="stylesheet" type="text/css" th:href="@{/js/easyui/themes/default/easyui.css}" /> 8 <link rel="stylesheet" type="text/css" th:href="@{/js/easyui/themes/icon.css}" /> 9 <script type="text/javascript" th:src="@{/js/easyui/jquery-1.8.0.min.js}"></script> 10 <script type="text/javascript" th:src="@{/js/easyui/jquery.easyui.min.js}"></script> 11 <script type="text/javascript" th:src="@{/js/easyui/locale/easyui-lang-zh_CN.js}"></script> 12 13 <link rel="stylesheet" type="text/css" th:href="@{/js/uploadify/uploadify.css}" /> 14 <script type="text/javascript" th:src="@{/js/uploadify/jquery.uploadify.min.js}"></script> 15 16 <!--ready事件--> 17 <script th:inline="javascript"> 18 var requestPath = [[${basePath}]]; 19 var errMsg = [[${errMsg}]]; 20 var basePath = requestPath + "/fileUpload"; 21 $(document).ready(function() { 22 $("#uploadify").uploadify({ 23 'uploader' : basePath + '/upload', 24 'swf' : requestPath + '/js/uploadify/uploadify.swf', 25 'cancelImg' : requestPath + '/js/uploadify/img/uploadify-cancel.png', 26 'queueID' : 'fileQueue',//与下面的id对应 27 'queueSizeLimit' : 8, 28 'fileExt' : '*.*', //控制可上传文件的扩展名,启用本项时需同时声明fileDesc 29 'auto' : false, 30 'multi' : true, 31 'simUploadLimit' : 2, 32 'method' : 'get', 33 'buttonText' : '选择文件', 34 'onUploadStart': function(file) {//上传开始时触发(每个文件触发一次) 35 $("#uploadify").uploadify("settings", 'formData',{'batchId': $('#hiddenInput').val()}) 36 }, 37 'onUploadSuccess' : function(file,data,response) {//上传完成时触发(每个文件触发一次) 38 alert(data); 39 data = eval("(" + data + ")"); 40 var batchId = data.batchId; 41 //alert(batchId); 42 var fileNameList = data.fileNameList; 43 //alert(fileNameList); 44 $('#hiddenInput').val(batchId); 45 $('#list').html(fileNameList); 46 } 47 }); 48 }); 49 </script> 50 51 </head> 52 <body> 53 <div style="margin: 20px 0;"></div> 54 <a class="easyui-linkbutton" onclick="javascript:$('#upload_dialog').dialog('open')">上传</a> 55 <div id="upload_dialog" class="easyui-dialog" title="文件上传" closed="true" style="width: 540px; height: auto" 56 data-options="iconCls:'icon-add',left:200,top:120,resizeable:true,modal:true,shadow:false"> 57 <div style="margin-left:20px; margin-right:20px"> 58 <div style="margin: 10px 0;"></div> 59 <div id="fileQueue"></div> 60 <div style="margin-top: 10px"></div> 61 <input type="file" name="file" id="uploadify" /> 62 <input type="hidden" name="hiddenInput" id="hiddenInput" value="" /> 63 <span id="list"></span> 64 <p> 65 <!-- 上传第一个未上传的文件 --> 66 <a href="javascript:$('#uploadify').uploadify('upload')" class="easyui-linkbutton"> 上传 </a> 67 <!-- 取消第一个未取消的文件 --> 68 <a href="javascript:$('#uploadify').uploadify('cancel')" class="easyui-linkbutton"> 取消上传 </a> 69 <a href="javascript:$('#uploadify').uploadify('upload','*')" class="easyui-linkbutton">上传所有文件</a> 70 <a href="javascript:$('#uploadify').uploadify('cancel','*')" class="easyui-linkbutton">取消所有上传</a> 71 </p> 72 </div> 73 </div> 74 </body> 75 </html>
后台Java代码:
1 @RequestMapping(value = "/upload", method = RequestMethod.POST) 2 @ResponseBody 3 public Map<String, Object> upload(HttpServletRequest request, @RequestParam(value = "Filedata", required = false) MultipartFile file 4 , @RequestParam(value = "batchId", required = false) String batchId 5 , Model model) { 6 if(file == null){ 7 Map<String, Object> error = new HashMap<>(); 8 error.put("info", "error"); 9 return error; 10 } 11 String savePath = ClassUtils.getDefaultClassLoader().getResource("").getPath(); 12 savePath = savePath.substring(1).replace("/", "\\") + "static\\upload\\test\\"; 13 File f1 = new File(savePath); 14 if (!f1.exists()) { 15 f1.mkdirs(); 16 } 17 String fileName = file.getOriginalFilename(); 18 //0. 处理fileName, IE和Google的fileName 会不同,ie会携带路径 19 if (!StringUtils.isBlank(fileName) && fileName.contains("\\")) { 20 int index = fileName.lastIndexOf("\\"); 21 fileName = fileName.substring(index + 1); 22 } 23 logger.info("文件上传--web-start"); 24 System.err.println("batchId=" + batchId); 25 try { 26 Long curTime = System.currentTimeMillis(); 27 if(batchId == null || batchId.equals("")){ 28 GUIDUtil myGUID = new GUIDUtil();//guid生成系列号 防止文件名冲突 29 batchId = myGUID.toString(); 30 fileNameList = new ArrayList<>(); 31 } 32 fileNameList.add(fileName); 33 String suffix = fileName.substring(fileName.lastIndexOf(".")); 34 String newFileName = (batchId + "-" + curTime + suffix).trim(); 35 FileUtils.uploadFile(file.getBytes(), savePath, newFileName); 36 } catch (IOException e) { 37 logger.error("文件上传--web-error"); 38 } 39 logger.info("文件上传--web-end"); 40 Map<String, Object> resultMap = new HashMap<String, Object>(); 41 resultMap.put("batchId", batchId); 42 resultMap.put("fileNameList", fileNameList.toString()); 43 return resultMap; 44 }
遇到的问题:
0、Thymeleaf的js中路径的表示问题:
一开始页面的上传按钮没有任何反应,查看控制台信息发现是swf文件没有找到,原来是Thymeleaf中的路径表示有问题,解决方式是路径采用IP、端口加上项目名称后面直接跟上js路径即可。
1、Spring Boot处理上传文件时出现异常:
org.springframework.web.multipart.support.MissingServletRequestPartException: Required request part 'file' is not present.
这个问题折腾了我很久,最后找到了一种解决方法,是将Controller中的参数 RequiredParam(value = "file") MultipartFile file 改成 RequiredParam(value = "Filedata") MultipartFile file,然后测试发现问题解决了。
2、Easyui和Uploadify兼容问题:
项目的前端框架用的是easyui,当我把easyui的相关包引入页面的时候,就发现了不兼容的现象。经过将css、js文件多次顺序、增减的测试,发现将原来Uploadify中的jquery包去掉即可兼容。
3、Easyui的dialog高度自适应时有阴影的问题:
在dialog的data-options中增加一个配置:shadow:false 即可解决问题。
4、Uploadify传参及接收数据:
这个只需要在js中添加两个方法:onUploadStart和onUploadSuccess,并且标注method='get',然后就可以很方便的传参和获取后台返回的值了。