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 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 validateUploadedFile(@RequestBody Map 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(); } } } }