| 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(); | 
|             } | 
|         } | 
|     } | 
|   | 
| } |