打开有些网站显示建设中,开发公司土建工程师绩效考核,wordpress 返回,石家庄哪里能做门户网站的引言
星期四的时候#xff0c;我遇到了一个文件上传的问题#xff0c;与以往不同的是#xff0c;这一次上传的是多个文件#xff0c;而且涉及到了久违的javascript代码。 虽然最后实现的并不尽如人意#xff0c;不过也算是完成了功能#xff0c;接下来就把我发现的一些问…引言
星期四的时候我遇到了一个文件上传的问题与以往不同的是这一次上传的是多个文件而且涉及到了久违的javascript代码。 虽然最后实现的并不尽如人意不过也算是完成了功能接下来就把我发现的一些问题和总结记录一下。
HTML部分展示
form id tempFile methodpost enctypemultipart/form-data!-- 指令模板文件上传 --div styletext-align: center;div classclearfix stylewidth:400px;margin:0 auto;input id templatesFile typefile multiplemultiple //div/div
/form上述代码可以看到只是一个简单的 form表单里面嵌套了一个 input 输入框这个 input 输入框的 type 类型是file值得注意的是如果是允许上传多个文件那么input输入框必须添加multiplemultiple 属性。 这里要说明一点由于使用 submit 按钮提交 form表单会造成页面刷新因此现在一般都采用按钮与 form 表单分离的方式使用 AJAX来异步上传数据。 如下所示
button classbtn btn-default onclicksendTemplates(); titleupload
上传模板文件
/buttonJS代码展示
/*** 上传模板文件* returns*/
function sendTemplates() {// 需要上传的文件
// var templates document.getElementById(templatesFile).files;var templates $(#templatesFile)[0].files;if (templates.length 2) {alert(上传失败一次最多两个文件);return;}var formdata new FormData();for (var i 0 ; i templates.length ; i) {formdata.append(temp i, templates[i]);}$.ajax({url : /manager/uploadTemplates,type : POST,data : formdata,processData : false,contentType : false,success : function(resultMap) {if (resultMap.code OK) {alert(上传成功);} else if (resultMap.code FAIL) {alert(resultMap.msg);}},error : function(e) {alert(服务器异常);}});
}代码已经保留了关键的代码部分剔除了一些无关紧要的操作。
Java代码实现
RequestMapping(value /uploadTemplates, method RequestMethod.POST)
ResponseBody
public MapString, Object uploadTemplates(HttpServletRequest request) {MultipartHttpServletRequest multipartRequest (MultipartHttpServletRequest) request;ListMultipartFile templatesList new ArrayList();for (int i 0 ; i 2 ; i) {templatesList.addAll(multipartRequest.getFiles(temp i));}MultipartFile[] templates new MultipartFile[templatesList.size()];templatesList.toArray(templates);MapString, Object result templateService.uploadTemplates(templates);return result;
}看到上面的代码我不得不说真的和 shi一样。不过目前我还没找到很好的办法。 好在 for 循环的 getFiles(...) 如果取不到值的话就会返回一个空的 List 不会直接抛出异常。 以上就是所有关键的代码部分下面来说一说调试过程中我使用过的几种方法以及觉得很坑的地方。
第一坑jQuery取files要加个[0]
回看js 部分的代码相信你已经注意到了
var templates $(#templatesFile)[0].files;这是通过jQuery选择器找到 idtemplatesFile 的 input标签并获取其中存储的 FileList 而FileList 并不是一个数组。如果希望将它转化成一个数组可以使用 Array.from(FileList) 不过不论是 FileList还是数组都不是重点重点是$(#templatesFile)[0] 一定要加上后面的这个 [0] 。而如果使用document.getElementById(...)就不必加 [0]。 这是因为 files 属性是原生js属性而不是jQuery属性因此需要通过这个 [0] 将jQuery对象转化为 js对象才能通过 .files 获得这个FileList
第二坑$.ajax 的data域要怎么写以及controller如何接收
说实话前面的 js 与 java部分的代码实在是迫不得已不过依然没有找到恰当合适的方法。 这个问题困扰了我整整一天的时间从星期四的下午开始研究一直到第二天星期五的上午才勉强以上面的代码跑通功能。 之前做过上传单个文件的功能比如这一篇《Java实现用户头像上传》。那天我乐观的以为只要前端能够获取到 files 数组然后后端的接口使用 MultipartFile[] 来接收就可以大功告成了像这样
RequestMapping(value /uploadTemplates, method RequestMethod.POST)
ResponseBody
public String uploadTemplates(MultipartFile[] templates) {// ...some codes
}但是前端的代码我试过N种方法依然无法成功接收到这个文件数组不论是这样 还是这样 亦或是将数组转化成String然后后台用String接收 都 完全没用 明明以前传其他类型的参数是OK的啊这到底是为什么 于是看到了 FormData 的解决方案。但是事情依然并不简单。 一开始我的思路是封装一个FormData对象然后把文件数组放入到一个value中并且指定一个key 这样后台通过 getFiles() 方法就可以获得整个文件列表了。但是并没有奏效。 在网上找了下原因看到了一些别人的代码**全都是每一个key放一个文件**原因是 原文链接FormData 对象的使用 简单的说 String、Blob、File可以被FormData传输如果是其他类型则会被转化成字符串然而对于FileList又会是怎样的情况呢我找到了下面这句话 Using the FormData API is the simplest and fastest, but has the disadvantage that data collected can not be stringified. 翻译过来就是使用FormData最简单也最高效但是有一个缺点是数据集合比如List或者数组无法被序列化为字符串。 我真的崩溃了也就是说我必须将文件列表或者数组中的每一个文件取出来分别给每一个文件指定一个Key才能成功的通过formdata传输到后台并接收。 所以才有了这样的代码
var formdata new FormData();
for (var i 0 ; i templates.length ; i) {formdata.append(temp i, templates[i]);
}和这样的代码
public MapString, Object uploadTemplates(HttpServletRequest request) {MultipartHttpServletRequest multipartRequest (MultipartHttpServletRequest) request;ListMultipartFile templatesList new ArrayList();for (int i 0 ; i 2 ; i) {templatesList.addAll(multipartRequest.getFiles(temp i));}// some other codes...
}到目前为止还没有找到更加简洁和高效的代码有哪位全栈的哥们可以告诉我吗 欢迎评论区留言哦非常感谢