layui修改源码使其多文件上传支持一次请求批量上传文件&Java控制器代码&上传数量限制&多次请求多线程问题解决

前言就不多说了,直接言归正传!!!

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

layui修改源码使其多文件上传支持一次请求批量上传文件&Java控制器代码&上传数量限制&多次请求多线程问题解决_第1张图片

  1. 源代码
// 使用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()
                    }
                })
            })
  1. 修改后的代码
 //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
  1. 部分配置文件
    
	
		    
		
		   
	
  1. 浏览器&控制器Ctl

layui修改源码使其多文件上传支持一次请求批量上传文件&Java控制器代码&上传数量限制&多次请求多线程问题解决_第2张图片

    @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 fileMap = new HashMap<>();
            List 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代码
  1. 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控制器代码&上传数量限制&多次请求多线程问题解决_第3张图片

  • 第四个问题(多次请求多线程问题):最后一个问题,得看个人是怎么处理或者多次请求的上传文件是什么操作了,如果仍然使用layui多个文件多次请求,那么到后台就是多个线程在处理;如果不是单纯的保存文件,而是保存后,对返回的数据再次处理;可能涉及到线程安全问题;可以这样解决
  1. 第一:在Java代码通加锁或者同步代码块
  2. 第二:还是把前端js源码修改,加个同步就好;
  3. 就不贴代码了;有问题欢迎留言讨论

 

 

 

 

你可能感兴趣的:(Java,JS,JavaWeb)