后端springmvc,前端html5的FormData实现文件断点上传

来源:互联网 发布:筒灯选择 知乎 编辑:程序博客网 时间:2024/05/18 12:01

后端代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package com.test.controller;
 
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.UUID;
 
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
 
@Controller
public class UploadController {
 
    @ResponseBody // 返回rest json
    @RequestMapping(value = {"/rest/saveUploadFileAsChunk"}, method = RequestMethod.POST, produces = "application/json")
    public File saveUploadFileAsChunk(@RequestParam(required = false) MultipartFile file,
            @RequestParam(required = true) Integer chunk,  // 分割块数
            @RequestParam(required = true) Integer chunks,  // 总分割数
            @RequestParam(required = true) String tempFileName //临时文件名  必须带后缀名
            throws Exception{
        if(null != file){
            // 保存临时文件
            String chunkName = tempFileName;
            if (chunk != null) {
                chunkName = chunk + "_" + tempFileName;
            }
            File savedFile = new File("普通存放文件的路径", chunkName);
            if (!savedFile.getParentFile().exists())
                savedFile.getParentFile().mkdirs();
            file.transferTo(savedFile);  //将MultipartFile转存到file对象
        }
         
        //如果到最后一个分割块,则做合并处理
        if (chunk != null && chunk + 1 == chunks) {
            String newFileName = UUID.randomUUID().toString().replace("-""").concat(".").concat(FilenameUtils.getExtension(tempFileName));
            BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(new File("普通存放文件的路径", newFileName)));
            // 遍历文件合并  chunks,循环将文件写入新的文件中,并且删除之前的临时文件 
            for (int i = 0; i < chunks; i++) {
                File tempFile = new File("普通存放文件的路径", i + "_" + tempFileName);
                byte[] bytes = FileUtils.readFileToByteArray(tempFile);   //将file对象解析城byte数组
                outputStream.write(bytes);
                outputStream.flush();
                tempFile.delete();
            }
            outputStream.flush();
            outputStream.close();
            File reallyFile = new File("普通存放文件的路径", newFileName);  //reallyFile即最后合并的文件
            return reallyFile;
        }
        return null;
    }
}

  前端代码: 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
var setsize = 10 * 1024;   //1024字节 = 1KB * 10  即每次10k
 
/**
 
*参数filepath就是本地文件路径,主要就是用于放在localStorage中确定唯一性
file : js的Blob对象
*/
function uplaod(filepath,file){
    var filesize = file.size;
    var filecount = filesize/setsize;   //计算出可以分成几块
 
    var i = localStorage.getItem(filepath);
    i = (i!=null && i!="")?parseInt(i):0;
 
    if(i < filecount){
        //新建一个FormData对象
        var formData = new FormData(); //++++++++++
        var blobfile;
        if((filesize - i * setsize) > setsize){
            blobfile = file.slice(i*setsize,(i+1)*setsize);
        }else{
            //代表是最后一此了
            blobfile = file.slice(i*setsize,filesize);
        }
 
        formData.append('chunk', i); //++++++++++当前文件块
        formData.append('chunks', Math.ceil(filecount)); //++++++++++  总块数
        formData.append("tempFileName",fileName);   //临时文件名 带uuid的
        formData.append('file', blobfile);
 
        if(i < filecount){
        $.ajax({
            url: PATROL_CONSTANTS.SRV_URL+"/rest/saveUploadFileAsChunk",
            type: 'POST',
            data: formData,
            processData: false,
            contentType: false,
            success: function (responseStr) {
                localStorage.setItem(filepath,i+1);
                var rs = filecount <= 0 ? "0%" : (Math.round((i+1) / Math.ceil(filecount) * 10000) / 100.00 + "%");
                console.log("进度百分比:"+rs);
                 
                uploadFile(filepath,file);  //递归调用
            },
            error: function (responseStr) {
                console.log("上传失败,重复尝试!");
                console.log(responseStr);
                uploadFile(filepath,file);
            }
        });
    }else{
        //上传完成后,则将对应的localStorage移除掉
        localStorage.removeItem(filepath);
    }
}

  

阅读全文
0 0
原创粉丝点击