feat: bug-523 支持1GB大文件的分片断点续传
This commit is contained in:
parent
63bb718b31
commit
7a2b031d43
|
|
@ -32,6 +32,7 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
|
||||
import javax.annotation.Resource;
|
||||
import javax.validation.Valid;
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotEmpty;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import java.io.FileOutputStream;
|
||||
|
|
@ -42,7 +43,9 @@ import java.nio.file.Path;
|
|||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipOutputStream;
|
||||
|
|
@ -66,6 +69,8 @@ public class FileController extends ControllerBase {
|
|||
@Resource
|
||||
private IFileUploadRecordService fileUploadRecordService;
|
||||
|
||||
private static final Map<String,String> FILE_PATH_MAP=new HashMap<>();
|
||||
|
||||
/**
|
||||
* 上传单个文件
|
||||
* @param file 要上传的文件
|
||||
|
|
@ -229,4 +234,54 @@ public class FileController extends ControllerBase {
|
|||
.contentType(MediaType.APPLICATION_OCTET_STREAM)
|
||||
.body(zipContent);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化分片上传
|
||||
* @param fileName 文件名
|
||||
* @return uploadId
|
||||
*/
|
||||
@GetMapping("/multipart/init")
|
||||
public ApiResult<String> initMultipartUpload(@Valid @RequestParam @NotBlank String fileName) {
|
||||
String filePath=buildFilePath(getFileType(fileName));
|
||||
String uploadId=fileUploadService.initMultipartUpload(filePath);
|
||||
FILE_PATH_MAP.put(uploadId,filePath);
|
||||
return ApiResult.success(uploadId);
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传分片
|
||||
* @param file 要上传的分片文件,名称为file
|
||||
* @param uploadId 上传id
|
||||
* @param chunkNumber 分片编号
|
||||
*/
|
||||
@PostMapping("/multipart/uploadChunk")
|
||||
public ApiResult<Void> uploadChunk(@RequestParam("file") MultipartFile file, @RequestParam String uploadId, @RequestParam Integer chunkNumber) throws IOException {
|
||||
String filePath = FILE_PATH_MAP.get(uploadId);
|
||||
VUtils.trueThrowBusinessError(StrUtil.isBlank(filePath)).throwMessage("文件不存在");
|
||||
fileUploadService.uploadChunk(file,filePath, uploadId, chunkNumber);
|
||||
return ApiResult.success();
|
||||
}
|
||||
|
||||
/**
|
||||
* 完成分片上传
|
||||
* @param uploadId 上传id
|
||||
* @return 文件url
|
||||
*/
|
||||
@PostMapping("/multipart/complete")
|
||||
public ApiResult<String> completeMultipartUpload(@RequestParam String uploadId) {
|
||||
String filePath = FILE_PATH_MAP.get(uploadId);
|
||||
VUtils.trueThrowBusinessError(StrUtil.isBlank(filePath)).throwMessage("文件不存在");
|
||||
return ApiResult.success(fileUploadService.completeMultipartUpload(filePath, uploadId));
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消分片上传
|
||||
* @param uploadId 上传id
|
||||
*/
|
||||
@PostMapping("/multipart/abort")
|
||||
public void abortMultipartUpload(@RequestParam String uploadId) {
|
||||
String filePath = FILE_PATH_MAP.get(uploadId);
|
||||
VUtils.trueThrowBusinessError(StrUtil.isBlank(filePath)).throwMessage("文件不存在");
|
||||
fileUploadService.abortMultipartUpload(filePath, uploadId);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,4 +24,12 @@ public interface FileUploadService {
|
|||
* @throws IOException
|
||||
*/
|
||||
String upload(String filePath, InputStream stream) throws IOException;
|
||||
|
||||
String initMultipartUpload(String filePath);
|
||||
|
||||
void uploadChunk(MultipartFile file,String filePath,String uploadId, int chunkNumber) throws IOException;
|
||||
|
||||
String completeMultipartUpload(String filePath,String uploadId);
|
||||
|
||||
void abortMultipartUpload(String filePath,String uploadId);
|
||||
}
|
||||
|
|
@ -2,8 +2,7 @@ package com.nflg.mobilebroken.starter.service.impl;
|
|||
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.aliyun.oss.OSS;
|
||||
import com.aliyun.oss.model.PutObjectRequest;
|
||||
import com.aliyun.oss.model.PutObjectResult;
|
||||
import com.aliyun.oss.model.*;
|
||||
import com.nflg.mobilebroken.starter.service.FileUploadService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
|
|
@ -14,6 +13,8 @@ import org.springframework.web.multipart.MultipartFile;
|
|||
import javax.annotation.Resource;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@Service
|
||||
@ConditionalOnProperty(name = "file.upload.type", havingValue = "oss")
|
||||
|
|
@ -41,4 +42,42 @@ public class OSSFileUploadService implements FileUploadService {
|
|||
//log.debug("上传文件结果: " + result);
|
||||
return StrUtil.format("{}/{}",domain, filePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String initMultipartUpload(String filePath) {
|
||||
InitiateMultipartUploadRequest request = new InitiateMultipartUploadRequest(bucketName, filePath);
|
||||
InitiateMultipartUploadResult result = ossClient.initiateMultipartUpload(request);
|
||||
return result.getUploadId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uploadChunk(MultipartFile file,String filePath,String uploadId, int chunkNumber) throws IOException {
|
||||
UploadPartRequest uploadPartRequest = new UploadPartRequest();
|
||||
uploadPartRequest.setBucketName(bucketName);
|
||||
uploadPartRequest.setKey(filePath);
|
||||
uploadPartRequest.setUploadId(uploadId);
|
||||
uploadPartRequest.setInputStream(file.getInputStream());
|
||||
uploadPartRequest.setPartSize(file.getSize());
|
||||
uploadPartRequest.setPartNumber(chunkNumber);
|
||||
ossClient.uploadPart(uploadPartRequest);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String completeMultipartUpload(String filePath,String uploadId) {
|
||||
ListPartsRequest listPartsRequest = new ListPartsRequest(bucketName, filePath, uploadId);
|
||||
PartListing partListing = ossClient.listParts(listPartsRequest);
|
||||
List<PartETag> partETags = new ArrayList<>();
|
||||
for (PartSummary part : partListing.getParts()) {
|
||||
partETags.add(new PartETag(part.getPartNumber(), part.getETag()));
|
||||
}
|
||||
CompleteMultipartUploadRequest completeRequest = new CompleteMultipartUploadRequest(bucketName, filePath, uploadId, partETags);
|
||||
ossClient.completeMultipartUpload(completeRequest);
|
||||
return StrUtil.format("{}/{}",domain, filePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abortMultipartUpload(String filePath,String uploadId) {
|
||||
AbortMultipartUploadRequest abortRequest = new AbortMultipartUploadRequest(bucketName, filePath, uploadId);
|
||||
ossClient.abortMultipartUpload(abortRequest);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue