新增文件分片进行上传接口
This commit is contained in:
parent
cc0a0c95f3
commit
71473b3caa
@ -125,6 +125,27 @@ public class WebFileController {
|
||||
return CommonResponse.success(BeanConvertUtil.copyBean(response, MultipartUploadVo.class));
|
||||
}
|
||||
|
||||
@SneakyThrows
|
||||
@PostMapping(value = "/v1/multipart-upload/file", consumes = MULTIPART_FORM_DATA_VALUE)
|
||||
@CrossOrigin
|
||||
public CommonResponse<MultipartUploadFileVo> multipartUploadFile(@Valid @RequestParam("appCode") String appCode,
|
||||
@Valid @RequestParam("bizScene") String bizScene,
|
||||
@Valid @RequestParam("fileName") String fileName,
|
||||
@Valid @RequestParam("tgtFileKey") String tgtFileKey,
|
||||
@Valid @RequestParam("uploadId") String uploadId,
|
||||
@Valid @RequestPart MultipartFile file) {
|
||||
MultipartUploadFileDto dto = MultipartUploadFileDto.builder()
|
||||
.appCode(appCode)
|
||||
.bizScene(bizScene)
|
||||
.fileName(fileName)
|
||||
.tgtFileKey(tgtFileKey)
|
||||
.fileContent(file.getBytes())
|
||||
.uploadId(uploadId)
|
||||
.build();
|
||||
MultipartUploadFileResponse response = fileService.multipartUploadFile(dto);
|
||||
return CommonResponse.success(BeanConvertUtil.copyBean(response, MultipartUploadFileVo.class));
|
||||
}
|
||||
|
||||
@PostMapping("/v1/multipart-upload/complete")
|
||||
@CrossOrigin
|
||||
@SneakyThrows
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
package cn.axzo.oss.client.vo;
|
||||
|
||||
import cn.axzo.oss.manager.api.dto.PartETag;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2023/8/15 11:56
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
public class MultipartUploadFileVo {
|
||||
|
||||
private String uploadId;
|
||||
|
||||
private List<PartETag> partETags;
|
||||
}
|
||||
@ -62,4 +62,6 @@ public interface BaseS3Service {
|
||||
Integer partNumber, long partSize);
|
||||
|
||||
String multipartUploadComplete(String bucketName, String tgtFileKey, String uploadId, List<PartETag> partETags);
|
||||
|
||||
List<PartETag> multipartUploadFile(String bucketName, String tgtFileKey, String uploadId, byte[] fileContent);
|
||||
}
|
||||
|
||||
@ -15,9 +15,11 @@ import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FilterInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.net.URLEncoder;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static cn.axzo.oss.common.constans.CommonConstants.APP_PRO_BUCKET_NAME;
|
||||
@ -193,6 +195,52 @@ public class AliOssServiceImpl implements AliOssService {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PartETag> multipartUploadFile(String bucketName, String tgtFileKey, String uploadId, byte[] fileContent) {
|
||||
OSS client = aliOssClient.getClient();
|
||||
try {
|
||||
List<PartETag> partETags = new ArrayList<PartETag>();
|
||||
// 每个分片的大小,用于计算文件有多少个分片。单位为字节。
|
||||
final long partSize = 10 * 1024 * 1024L; //1 MB。
|
||||
|
||||
// 根据上传的数据大小计算分片数。以本地文件为例,说明如何通过File.length()获取上传数据的大小。
|
||||
long fileLength = fileContent.length;
|
||||
int partCount = (int) (fileLength / partSize);
|
||||
if (fileLength % partSize != 0) {
|
||||
partCount++;
|
||||
}
|
||||
// 遍历分片上传。
|
||||
for (int i = 0; i < partCount; i++) {
|
||||
long startPos = i * partSize;
|
||||
long curPartSize = (i + 1 == partCount) ? (fileLength - startPos) : partSize;
|
||||
UploadPartRequest partRequest = new UploadPartRequest();
|
||||
// 阿里云 oss 文件根目录
|
||||
partRequest.setBucketName(bucketName);
|
||||
// 文件key
|
||||
partRequest.setKey(tgtFileKey);
|
||||
// 分片上传uploadId
|
||||
partRequest.setUploadId(uploadId);
|
||||
// 分片文件
|
||||
InputStream inputStream = new ByteArrayInputStream(fileContent);
|
||||
inputStream.skip(startPos);
|
||||
partRequest.setInputStream(inputStream);
|
||||
// 分片大小。除了最后一个分片没有大小限制,其他的分片最小为100 KB。
|
||||
partRequest.setPartSize(curPartSize);
|
||||
// 分片号。每一个上传的分片都有一个分片号,取值范围是1~10000,如果超出这个范围,OSS将返回InvalidArgument的错误码。
|
||||
partRequest.setPartNumber(i + 1);
|
||||
// 每个分片不需要按顺序上传,甚至可以在不同客户端上传,OSS会按照分片号排序组成完整的文件。
|
||||
UploadPartResult uploadPartResult = client.uploadPart(partRequest);
|
||||
// 每次上传分片之后,OSS的返回结果包含PartETag。PartETag将被保存在partETags中。
|
||||
partETags.add(uploadPartResult.getPartETag());
|
||||
}
|
||||
return partETags;
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new BizException(MULTIPART_UPLOAD_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String multipartUploadComplete(String bucketName, String tgtFileKey, String uploadId, List<PartETag> partETags) {
|
||||
OSS client = aliOssClient.getClient();
|
||||
|
||||
@ -2,6 +2,7 @@ package cn.axzo.oss.manager.api;
|
||||
|
||||
import cn.axzo.oss.manager.api.dto.PartETag;
|
||||
import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.MultipartUploadFileDto;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
@ -46,4 +47,6 @@ public interface FileManager {
|
||||
PartETag multipartUpload(String bucketName, String tgtFileKey, byte[] fileContent, MultipartUploadDto dto);
|
||||
|
||||
String multipartUploadComplete(String bucketName, String tgtFileKey, String uploadId, List<PartETag> partETags);
|
||||
|
||||
List<PartETag> multipartUploadFile(String bucketName, String tgtFileKey, byte[] fileContent, MultipartUploadFileDto dto);
|
||||
}
|
||||
|
||||
@ -0,0 +1,39 @@
|
||||
package cn.axzo.oss.manager.api.dto.request;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2023/8/15 11:39
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class MultipartUploadFileDto {
|
||||
|
||||
@NotBlank
|
||||
private String appCode;
|
||||
|
||||
@NotBlank
|
||||
private String bizScene;
|
||||
|
||||
@NotBlank
|
||||
private String fileName;
|
||||
|
||||
@NotBlank
|
||||
private String tgtFileKey;
|
||||
|
||||
private byte[] fileContent;
|
||||
|
||||
/**
|
||||
* oss上传时的上传id
|
||||
*/
|
||||
private String uploadId;
|
||||
}
|
||||
@ -0,0 +1,22 @@
|
||||
package cn.axzo.oss.manager.api.dto.response;
|
||||
|
||||
import cn.axzo.oss.manager.api.dto.PartETag;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* @Author: liyong.tian
|
||||
* @Date: 2023/8/15 13:39
|
||||
* @Description:
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
public class MultipartUploadFileResponse {
|
||||
|
||||
private String uploadId;
|
||||
|
||||
private List<PartETag> partETags;
|
||||
}
|
||||
@ -5,6 +5,7 @@ import cn.axzo.oss.integration.s3.AliOssService;
|
||||
import cn.axzo.oss.manager.api.FileManager;
|
||||
import cn.axzo.oss.manager.api.dto.PartETag;
|
||||
import cn.axzo.oss.manager.api.dto.request.MultipartUploadDto;
|
||||
import cn.axzo.oss.manager.api.dto.request.MultipartUploadFileDto;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
@ -70,6 +71,12 @@ public class FileManagerImpl implements FileManager {
|
||||
return BeanConvertUtil.copyBean(partETag, PartETag.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<PartETag> multipartUploadFile(String bucketName, String tgtFileKey, byte[] fileContent, MultipartUploadFileDto dto) {
|
||||
List<com.aliyun.oss.model.PartETag> partETags = aliOssService.multipartUploadFile(bucketName, tgtFileKey, dto.getUploadId(), dto.getFileContent());
|
||||
return BeanConvertUtil.copyList(partETags, PartETag.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String multipartUploadComplete(String bucketName, String tgtFileKey, String uploadId, List<PartETag> partETags) {
|
||||
List<com.aliyun.oss.model.PartETag> partETagList = convertPartETags(partETags);
|
||||
|
||||
@ -42,4 +42,6 @@ public interface FileService {
|
||||
MultipartUploadResponse multipartUpload(MultipartUploadDto dto);
|
||||
|
||||
FileInformationResponse multipartUploadComplete(MultipartUploadCompleteDto dto);
|
||||
|
||||
MultipartUploadFileResponse multipartUploadFile(MultipartUploadFileDto dto);
|
||||
}
|
||||
|
||||
@ -10,7 +10,6 @@ import cn.axzo.oss.common.enums.CodeEnum;
|
||||
import cn.axzo.oss.common.enums.FileClassEnum;
|
||||
import cn.axzo.oss.common.enums.FileStatusEnum;
|
||||
import cn.axzo.oss.common.exception.BizException;
|
||||
import cn.axzo.oss.common.utils.BeanConvertUtil;
|
||||
import cn.axzo.oss.common.utils.JsonUtil;
|
||||
import cn.axzo.oss.common.utils.Utility;
|
||||
import cn.axzo.oss.dal.entity.*;
|
||||
@ -181,6 +180,21 @@ public class FileServiceImpl implements FileService {
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MultipartUploadFileResponse multipartUploadFile(MultipartUploadFileDto dto) {
|
||||
FileUploadConfig fileUploadConfig = getFileUploadConfig(dto.getAppCode(), dto.getBizScene());
|
||||
// 判断容量
|
||||
isFileConform(fileUploadConfig, dto.getFileContent().length, dto.getFileName());
|
||||
|
||||
List<PartETag> partETags = fileManager.multipartUploadFile(fileUploadConfig.getBucketName(),
|
||||
dto.getTgtFileKey(), dto.getFileContent(), dto);
|
||||
MultipartUploadFileResponse response = MultipartUploadFileResponse.builder()
|
||||
.uploadId(dto.getUploadId())
|
||||
.partETags(partETags)
|
||||
.build();
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileInformationResponse multipartUploadComplete(MultipartUploadCompleteDto dto) {
|
||||
FileUploadConfig fileUploadConfig = getFileUploadConfig(dto.getAppCode(), dto.getBizScene());
|
||||
|
||||
Loading…
Reference in New Issue
Block a user