虽然末了实现的差强人意,不过也算是完成了功能,接下来就把我创造的一些问题和总结记录一下。
HTML部分展示<form id =\"大众tempFile\公众 method=\"大众post\"大众 enctype=\公众multipart/form-data\"大众><!-- 指令模板文件上传 --><div style=\"大众text-align: center;\公众><div class=\公众clearfix\"大众 style=\公众width:400px;margin:0 auto;\"大众> <input id =\"大众templatesFile\"大众 type=\"大众file\公众 multiple=\"大众multiple\公众 /> </div> </div></form>
上述代码可以看到,只是一个大略的 form表单,里面嵌套了一个 input 输入框,这个 input 输入框的 type 类型是file,值得把稳的是,如果是许可上传多个文件,那么input输入框必须添加multiple=\公众multiple\公众 属性。
这里要解释一点,由于利用 submit 按钮提交 form表单会造成页面刷新,因此,现在一样平常都采取按钮与 form 表单分离的办法,利用 AJAX来异步上传数据。 如下所示:
<button class=\"大众btn btn-default\"大众 onclick=\公众sendTemplates();\公众 title=\"大众upload\公众>上传模板文件</button>JS代码展示
/ 上传模板文件 @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)@ResponseBodypublic Map<String, Object> uploadTemplates(HttpServletRequest request) {MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;List<MultipartFile> 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);Map<String, Object> result = templateService.uploadTemplates(templates);return result;}
看到上面的代码,我不得不说,真的和 shi 一样。不过目前我还没找到很好的办法。
好在 for 循环的 getFiles(...) 如果取不到值的话,就会返回一个空的 List 不会直接抛出非常。
以上便是所有关键的代码部分,下面来说一说调试过程中我利用过的几种方法,以及以为很坑的地方。
第一坑:jQuery取files要加个[0]回看js 部分的代码,相信你已经把稳到了:
var templates = $(\"大众#templatesFile\"大众)[0].files;
而FileList 并不是一个数组。如果希望将它转化成一个数组,可以利用 Array.from(FileList)
不过不论是 FileList还是数组,都不是重点,重点是$(\公众#templatesFile\"大众)[0] 一定要加上后面的这个 [0] 。而如果利用document.getElementById(\"大众...\"大众)就不必加 [0]。 这是由于 files 属性是原生js属性,而不是jQuery属性,因此须要通过这个 [0] 将jQuery工具转化为 js工具,才能通过 .files 得到这个FileList !
说实话,前面的 js 与 java部分的代码实在是迫不得已,不过依然没有找到恰当得当的方法。
这个问题困扰了我整整一天的韶光,从星期四的下午开始研究一贯到第二天星期五的上午才勉强以上面的代码跑通功能。
之前做过上传单个文件的功能。那天我乐不雅观的以为,只要前端能够获取到 files 数组,然后后真个接口利用 MultipartFile[] 来吸收就可以大功告成了!
像这样:
@RequestMapping(value = \"大众/uploadTemplates\"大众, method = RequestMethod.POST)@ResponseBodypublic String uploadTemplates(MultipartFile[] templates) { // ...some codes}
但是前真个代码我试过N种方法依然无法成功吸收到这个文件数组!
不论是这样:
还是这样:
亦或是将数组转化成String,然后后台用String吸收:
都 完!
全!
没!
用!
明明以前传其他类型的参数是OK的啊!
这到底是为什么?
于是看到了 FormData 的办理方案。但是事情依然并!
不!
简!
单!
一开始我的思路是封装一个FormData工具,然后把文件数组整体放入到一个value中,并且指定一个key ,这样后台通过 getFiles() 方法就可以得到全体文件列表了。
然鹅,并无卵用!
在网上找了下缘故原由,看到了一些别人的代码,全都是每一个key放一个文件!
缘故原由是:
大略的说, String、Blob、File可以被FormData传输(把稳这里是单个File类型的文件),如果是其他类型,则会被转化成字符串,然而,对付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传输到后台并吸收。
以是才有了这样的代码:
// JSvar formdata = new FormData();for (var i = 0 ; i < templates.length ; i++) {formdata.append(\"大众temp\"大众 + i, templates[i]);}
和这样的代码:
// java controllerpublic Map<String, Object> uploadTemplates(HttpServletRequest request) {MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;List<MultipartFile> templatesList = new ArrayList<>();for (int i = 0 ; i < 2 ; i++) {templatesList.addAll(multipartRequest.getFiles(\"大众temp\"大众 + i));}// some other codes...}
到目前为止,还没有找到更加简洁和高效的代码,有哪位全栈的哥们可以见告我吗?
欢迎评论区留言哦!
非常感谢!
---欢迎关注【Java圣斗士】,我是你们的小可爱(✪ω✪) Morty---
---专注IT职场履历、IT技能分享的灵魂写手---
---每天带你领略IT的魅力---
---期待与您陪伴!
---