6
jinlin
2023-11-29 b21945e7dea2daa8b30bee3cdd4bca91277e3b5f
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package com.zt.modules.oss.controller;
 
import com.zt.common.servlet.Result;
import com.zt.modules.oss.cloud.AbstractStorageService;
import io.swagger.annotations.Api;
import org.apache.tomcat.util.http.fileupload.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
 
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.util.Map;
 
@RestController
@RequestMapping("sys/oss")
@Api(tags = "文件上传")
public class chunkUploadController {
    @Autowired
    private AbstractStorageService storageService;
 
    @PostMapping("/upload_chunk/")
    public Result<Boolean> uploadFile(@RequestParam("file") MultipartFile file,
                                      @RequestParam("uid") String uid,
                                      @RequestParam("chunk") int chunk,
                                      @RequestParam("filter_type") String filterType,
                                      @RequestParam("fileName") String fileName,
                                      @RequestParam(value = "chunks", required = false) String chunks) {
        try {
            String tempUploadDir = storageService.getConfig().getLocalPath() + File.separator + "TEMP_UPLOAD";
            File dir = new File(tempUploadDir);
            if (!dir.exists()) {
                dir.mkdirs();
            }
            if ("undefined".equals(chunks)) {
                String filePath = tempUploadDir + File.separator + "file_" + uid;
                File destFile = new File(filePath);
                try {
                    file.transferTo(destFile);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return Result.ok(false);
            } else {
                // 如果chunks有值,说明是分块上传的逻辑
                int numberOfChunks = Integer.parseInt(chunks);
                String uploadDir = tempUploadDir + File.separator + uid;
                File chunkdir = new File(uploadDir);
                if (!chunkdir.exists()) {
                    chunkdir.mkdirs();
                }
 
                String chunkFileName = uploadDir + File.separator + chunk;
                byte[] fileBytes = file.getBytes();
                try (FileOutputStream fos = new FileOutputStream(chunkFileName)) {
                    fos.write(fileBytes);
                }
                if (chunk == numberOfChunks - 1) {
                    // 所有文件块上传完成,可以将它们合并成最终文件
                    String finalFileName = tempUploadDir + File.separator + "file_" + uid;
                    File finalFile = new File(finalFileName);
                    try (FileOutputStream fos = new FileOutputStream(finalFile)) {
                        for (int i = 0; i < numberOfChunks; i++) {
                            String chunkFilePath = uploadDir + File.separator + i;
                            File chunkFile = new File(chunkFilePath);
                            try (FileInputStream fis = new FileInputStream(chunkFile)) {
                                byte[] buffer = new byte[1024];
                                int bytesRead;
                                while ((bytesRead = fis.read(buffer)) != -1) {
                                    fos.write(buffer, 0, bytesRead);
                                }
                            }
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                        return Result.ok(false);
                    } finally {
                        // 删除临时文件块目录及其内容
                        try {
                            FileUtils.deleteDirectory(chunkdir);
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            return Result.ok(true);
        } catch (IOException e) {
            e.printStackTrace();
            return Result.ok();
        }
    }
 
    @PostMapping("/upload_success/")
    public Result<Boolean> validateUploadedFile(@RequestBody Map<String, Object> fileData) {
        String name = (String) fileData.get("name");
        String uid = (String) fileData.get("uid");
        String md5 = (String) fileData.get("md5");
        int chunks = (int) fileData.get("chunks");
        String filterType = (String) fileData.get("filter_type");
 
        if (validateFile(name, uid, md5, chunks, filterType)) {
                return Result.ok(true);
        } else {
            return Result.ok(false);
        }
    }
 
    // 文件校验方法,根据文件名、uid、MD5哈希值、块数等参数进行校验
    private boolean validateFile(String name, String uid, String md5, int chunks, String filterType) {
        String filePath = storageService.getConfig().getLocalPath() + File.separator + "TEMP_UPLOAD" + File.separator + "file_" + uid;
        String calculatedMd5 = calculateFileMd5(filePath);
        if (calculatedMd5 != null && calculatedMd5.equals(md5)) {
            // 如果MD5校验通过,返回 true
            return true;
        } else {
            // 如果MD5校验失败,返回 false
            return false;
        }
    }
 
    private String calculateFileMd5(String filePath) {
        FileInputStream fileInputStream = null;
        DigestInputStream digestInputStream = null;
 
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            MessageDigest md = MessageDigest.getInstance("MD5");
            byte[] buffer = new byte[1024];
            int length = -1;
            while ((length = fis.read(buffer, 0, 1024)) != -1) {
                md.update(buffer, 0, length);
            }
            byte[] md5Bytes = md.digest();
            StringBuffer hexValue = new StringBuffer();
            for (int i = 0; i < md5Bytes.length; i++) {
                int val = ((int) md5Bytes[i]) & 0xff;
                if (val < 16)
                    hexValue.append("0");
                hexValue.append(Integer.toHexString(val));
            }
            return hexValue.toString();
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (digestInputStream != null) {
                    digestInputStream.close();
                }
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
 
}