前言就不多说了,直接言归正传!!!
- 第一个问题(多文件多次请求):使用layui上传多文件的js源码是在upload.js中,当然果如你使用的是layui.all.js,那这个上传文件的代码是在layui.all.js文件里。直接讲最关键的上传部分源码就好,layui的做法是使用layui.each()遍历文件队列依次发送Ajax(post,默认使用异步)请求到后台的。
- 解决方法(多文件一次请求):看懂的关键部分,要想一次请求携带所有文件,先所有文件遍历放在同一个FormData中,最后最后在发送一次Ajax请求。当然这样虽然可以做到一次上传所有文件,但是对应的上传成功或失败后修改每个文件的状态还没做好,所有还得添加几行代码,稍见下方代码

- 源代码
// 使用layui.all.js 中的代码示范(格式化后 lines=4323 or search=请求上传接口出现异常)
layui.each(a, function (e, a) {
var r = new FormData;
r.append(l.field, a), layui.each(l.data, function (e, i) {
i = "function" == typeof i ? i() : i, r.append(e, i)
}), i.ajax({
url: l.url,
type: "post",
data: r,
contentType: !1,
processData: !1,
dataType: "json",
headers: l.headers || {},
success: function (i) {
t++, d(e, i), u()
},
error: function () {
n++, o.msg("请求上传接口出现异常"), m(e), u()
}
})
})- 修改后的代码
//self begin(合并资源上传)
var r_my = new FormData;
var e1 = '';//每个文件的标识,为修改文件状态准备
layui.each(a, function (e, a) {
e1 = e1 + (e + '&');
r_my.append(l.field, a)
})
layui.each(l.data, function (e1, i) {
i = "function" == typeof i ? i() : i, r_my.append(e1, i)
})
i.ajax({
url: l.url,
type: "post",
data: r_my,
contentType: !1,
processData: !1,
dataType: "json",
headers: l.headers || {},
success: function (i) {
var arr = e1.split('&');//遍历每个文件唯一标识修改状态
for (var j = 0; j < arr.length - 1; j++) {
t++, d(arr[j], i), u()
}
},
error: function () {
var arr = e1.split('&');
for (var j = 0; j < arr.length - 1; j++) {
n++, o.msg("请求上传接口出现异常"), m(arr[j]), u()
}
}
})以上呢,就基本满足各位的需求了,但是,可能还有其它的地方影响到,没有发现(每个文件的其它操作),毕竟人家写了一堆都是针对单个文件的,所以如果大家发现有什么问题或者修改好了的,欢迎在评论区发出,以便后来人参考
- 第二个问题(Java后台控制器类的写法):这里用的是springMVC中MultipartResolver处理文件上传;另外在Ctl中因为前端用的是layui的,而layui原本是单个文件上传(r_my.append(l.field, a)),所以在Ctl参数接收用 !!!"file" !!!【可以在js和java参数中,修改为字符串‘files’,有兴趣修改试试】
@RequestParam("file") MultipartFile[] files
- 部分配置文件
<!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"/>
<!-- 指定所上传文件的总大小不能超过10MB。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 -->
<property name="maxUploadSize" value="10485760"/>
</bean>- 浏览器&控制器Ctl

@RequestMapping(value = "/uploadZfzl")
@ResponseBody
public String uploadZfzl(@RequestParam("file") MultipartFile[] files, HttpServletRequest request) throws Exception {
String result = "上传失败";
IFService fService = new IFServiceImpl();
if (null != files && files.length > 0) {
String curPageFileId = request.getParameter("curPageFileId");
Map<String, Object> fileMap = new HashMap<>();
List<DzdaDto> fileDtoList = new ArrayList<>();
for (MultipartFile file : files) {
String entryName = file.getOriginalFilename();
String indexName = entryName.substring(entryName.lastIndexOf(".") + 1);
if ("jpg".equalsIgnoreCase(indexName) || "png".equalsIgnoreCase(indexName) || "pdf".equalsIgnoreCase(indexName)) {//jpg,png,pdf
byte[] fileBytes = file.getBytes();
DzdaDto fileDto = new DzdaDto();
fileDto.setFileType(indexName);
fileDto.setFileName(entryName);
fileDto.setFileContent(fileBytes);
fileDto.setWjlxDm("03");
fileDtoList.add(fileDto);
}
}
fileMap.put("curPageFileId", curPageFileId);
fileMap.put("fileDtoList", fileDtoList);
try {
fService .uploadZfzl(fileMap);
result = "上传成功";
} catch (Exception e) {
log.error("上传失败!", e);
result = "上传失败";
}
}
return result;
}- 第三个问题(上传数量限制):使用layui虽然能限制,但是只是限制所有未上传文件的数量,假设限制4,如果先上传3个成功,在选择3个,并上传是允许的。可能就不是想要的效果,所有文件总数的限制了。马上贴出js代码
- js控制列表数代码(ps:return结束不了代码执行上传操作,所以使用报错方式结束[至少我的电脑是这样的],另外不要想着在choose:{}里面判断,很复杂,虽然可能更加人性化,截图看看)
, before: function (obj) { //choose 回调之后、done/error 回调之前触发
var fileTableNum = $('#fbzlPre tr').length;
if (fileTableNum > 4) {
layer.alert('请检查附报资料的数量', {icon: 2, skin: 'layer-ext-moon'});
die;//无法return,使用报错结束上传
// return;
}
}
- 第四个问题(多次请求多线程问题):最后一个问题,得看个人是怎么处理或者多次请求的上传文件是什么操作了,如果仍然使用layui多个文件多次请求,那么到后台就是多个线程在处理;如果不是单纯的保存文件,而是保存后,对返回的数据再次处理;可能涉及到线程安全问题;可以这样解决
- 第一:在Java代码通加锁或者同步代码块
- 第二:还是把前端js源码修改,加个同步就好;
- 就不贴代码了;有问题欢迎留言讨论
版权声明:本文为JzCm__原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。