|
|
@@ -0,0 +1,187 @@
|
|
|
+package cn.reghao.oss.sdk;
|
|
|
+
|
|
|
+import cn.reghao.jutil.jdk.http.UploadParam;
|
|
|
+import cn.reghao.jutil.jdk.http.WebRequest;
|
|
|
+import cn.reghao.jutil.jdk.http.WebResponse;
|
|
|
+import cn.reghao.jutil.jdk.io.FilePart;
|
|
|
+import cn.reghao.jutil.jdk.result.WebResult;
|
|
|
+import cn.reghao.jutil.jdk.security.DigestUtil;
|
|
|
+import cn.reghao.jutil.jdk.serializer.JsonConverter;
|
|
|
+import cn.reghao.jutil.tool.http.DefaultWebRequest;
|
|
|
+import cn.reghao.oss.api.rest.UploadFilePart;
|
|
|
+import cn.reghao.oss.api.rest.UploadFileRet;
|
|
|
+import cn.reghao.oss.api.rest.UploadPrepareRet;
|
|
|
+import cn.reghao.oss.api.rest.UploadedPart;
|
|
|
+import com.google.gson.reflect.TypeToken;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+
|
|
|
+import java.io.*;
|
|
|
+import java.lang.reflect.Type;
|
|
|
+import java.net.URI;
|
|
|
+import java.net.URISyntaxException;
|
|
|
+import java.net.http.HttpClient;
|
|
|
+import java.net.http.HttpRequest;
|
|
|
+import java.net.http.HttpResponse;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
+
|
|
|
+/**
|
|
|
+ * @author reghao
|
|
|
+ * @date 2023-06-02 16:19:04
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+public class ObjectMultipartUploadService {
|
|
|
+ private final String endpoint;
|
|
|
+ private final FilePart filePart = new FilePart();
|
|
|
+ private final HttpClient httpClient = HttpClient.newBuilder().build();
|
|
|
+ private final WebRequest webRequest = new DefaultWebRequest();
|
|
|
+
|
|
|
+ public ObjectMultipartUploadService(String endpoint) {
|
|
|
+ this.endpoint = endpoint;
|
|
|
+ }
|
|
|
+
|
|
|
+ public void create() throws URISyntaxException, IOException, InterruptedException {
|
|
|
+ MultiPartBodyPublisher publisher = new MultiPartBodyPublisher();
|
|
|
+ publisher.addPart("filename", "1.zip")
|
|
|
+ .addPart("size", 1+"")
|
|
|
+ .addPart("sha256sum", "1234567890");
|
|
|
+
|
|
|
+ String authorization = "";
|
|
|
+ String api = endpoint + "/?create";
|
|
|
+ HttpRequest httpRequest = HttpRequest.newBuilder(new URI(api))
|
|
|
+ .version(HttpClient.Version.HTTP_1_1)
|
|
|
+ .header("Authorization", authorization)
|
|
|
+ .header("Content-Type", "multipart/form-data; boundary=" + publisher.getBoundary())
|
|
|
+ .POST(publisher.build())
|
|
|
+ .build();
|
|
|
+
|
|
|
+ HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
|
|
|
+ String body = httpResponse.body();
|
|
|
+ Type type = new TypeToken<WebResult<UploadPrepareRet>>(){}.getType();
|
|
|
+ WebResult<UploadPrepareRet> webResult = JsonConverter.jsonToObject(body, type);
|
|
|
+ if (webResult.getCode() != 0) {
|
|
|
+ String errMsg = webResult.getMsg();
|
|
|
+ }
|
|
|
+
|
|
|
+ UploadPrepareRet uploadPrepareRet = webResult.getData();
|
|
|
+ System.out.println();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void get() throws URISyntaxException, IOException, InterruptedException {
|
|
|
+ String authorization = "";
|
|
|
+ String api = endpoint + "/?multipart";
|
|
|
+ HttpRequest httpRequest = HttpRequest.newBuilder(new URI(api))
|
|
|
+ .version(HttpClient.Version.HTTP_1_1)
|
|
|
+ .header("Authorization", authorization)
|
|
|
+ //.header("Content-Type", "multipart/form-data; boundary=" + publisher.getBoundary())
|
|
|
+ .GET()
|
|
|
+ .build();
|
|
|
+
|
|
|
+ HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
|
|
|
+ String body = httpResponse.body();
|
|
|
+ Type type = new TypeToken<WebResult<UploadedPart>>(){}.getType();
|
|
|
+ WebResult<UploadedPart> webResult = JsonConverter.jsonToObject(body, type);
|
|
|
+ if (webResult.getCode() != 0) {
|
|
|
+ String errMsg = webResult.getMsg();
|
|
|
+ }
|
|
|
+
|
|
|
+ UploadedPart uploadedPart = webResult.getData();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * jdk http 实现
|
|
|
+ * 存在 bug: https://bugs.openjdk.org/browse/JDK-8222968
|
|
|
+ *
|
|
|
+ * @param
|
|
|
+ * @return
|
|
|
+ * @date 2023-05-24 14:56:50
|
|
|
+ */
|
|
|
+ public void postObject1(byte[] bytes, UploadFilePart uploadFilePart)
|
|
|
+ throws URISyntaxException, IOException, InterruptedException {
|
|
|
+ MultiPartBodyPublisher publisher = new MultiPartBodyPublisher();
|
|
|
+ ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
|
|
+ publisher.addPart("file", () -> bais, uploadFilePart.getFilename(), "")
|
|
|
+ //.addPart("file", Path.of(""))
|
|
|
+ .addPart("channelId", uploadFilePart.getChannelId()+"")
|
|
|
+ .addPart("identifier", uploadFilePart.getIdentifier())
|
|
|
+ .addPart("filename", uploadFilePart.getFilename())
|
|
|
+ .addPart("relativePath", uploadFilePart.getRelativePath())
|
|
|
+ .addPart("totalSize", uploadFilePart.getTotalSize()+"")
|
|
|
+ .addPart("chunkSize", uploadFilePart.getChunkSize()+"")
|
|
|
+ .addPart("currentChunkSize", uploadFilePart.getCurrentChunkSize()+"")
|
|
|
+ .addPart("totalChunks", uploadFilePart.getTotalChunks()+"")
|
|
|
+ .addPart("chunkNumber", uploadFilePart.getChunkNumber()+"");
|
|
|
+
|
|
|
+ String authorization = "";
|
|
|
+ String api = endpoint + "/?multipart";
|
|
|
+ HttpRequest httpRequest = HttpRequest.newBuilder(new URI(api))
|
|
|
+ .version(HttpClient.Version.HTTP_1_1)
|
|
|
+ .header("Authorization", authorization)
|
|
|
+ .header("Content-Type", "multipart/form-data; boundary=" + publisher.getBoundary())
|
|
|
+ .POST(publisher.build())
|
|
|
+ .build();
|
|
|
+
|
|
|
+ HttpResponse<String> httpResponse = httpClient.send(httpRequest, HttpResponse.BodyHandlers.ofString());
|
|
|
+ System.out.println();
|
|
|
+ }
|
|
|
+
|
|
|
+ public void postObject(byte[] bytes, UploadFilePart uploadFilePart) {
|
|
|
+ UploadParam uploadParam = new UploadParam(bytes, "");
|
|
|
+ Map<String, String> params = new HashMap<>();
|
|
|
+ params.put("channelId", uploadFilePart.getChannelId()+"");
|
|
|
+ params.put("identifier", uploadFilePart.getIdentifier());
|
|
|
+ params.put("filename", uploadFilePart.getFilename());
|
|
|
+ params.put("relativePath", uploadFilePart.getRelativePath());
|
|
|
+ params.put("totalSize", uploadFilePart.getTotalSize()+"");
|
|
|
+ params.put("chunkSize", uploadFilePart.getChunkSize()+"");
|
|
|
+ params.put("currentChunkSize", uploadFilePart.getCurrentChunkSize()+"");
|
|
|
+ params.put("totalChunks", uploadFilePart.getTotalChunks()+"");
|
|
|
+ params.put("chunkNumber", uploadFilePart.getChunkNumber()+"");
|
|
|
+ uploadParam.setTextParams(params);
|
|
|
+
|
|
|
+ String api = endpoint + "/?multipart";
|
|
|
+ WebResponse webResponse = webRequest.upload(api, uploadParam);
|
|
|
+ int statusCode = webResponse.getStatusCode();
|
|
|
+ if (statusCode != 200) {
|
|
|
+ log.error("请求失败");
|
|
|
+ }
|
|
|
+
|
|
|
+ String body = webResponse.getBody();
|
|
|
+ Type type = new TypeToken<WebResult<UploadFileRet>>(){}.getType();
|
|
|
+ WebResult<UploadFileRet> webResult = JsonConverter.jsonToObject(body, type);
|
|
|
+ if (webResult.getCode() != 0) {
|
|
|
+ String errMsg = webResult.getMsg();
|
|
|
+ }
|
|
|
+
|
|
|
+ UploadFileRet uploadFileRet = webResult.getData();
|
|
|
+ if (!uploadFileRet.isMerged()) {
|
|
|
+ log.info("继续上传");
|
|
|
+ } else {
|
|
|
+ log.info("分片上传并合并完成");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public void upload(File file, int channelId) throws Exception {
|
|
|
+ String identifier = DigestUtil.sha256sum(new FileInputStream(file));
|
|
|
+ String filename = file.getName();
|
|
|
+ String relativePath = file.getAbsolutePath();
|
|
|
+
|
|
|
+ long totalSize = file.length();
|
|
|
+ // 分段大小在 5MB - 5GB 之间,只有最后一个分段才允许小于 5MB,不可避免的
|
|
|
+ int chunkSize = filePart.getPartSize();
|
|
|
+ long totalChunks = totalSize/chunkSize;
|
|
|
+ if (totalSize % chunkSize != 0) {
|
|
|
+ totalChunks += 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (long i = 0; i < totalChunks; i++) {
|
|
|
+ long start = i*chunkSize;
|
|
|
+ byte[] part = filePart.getPart(file.getAbsolutePath(), chunkSize, start);
|
|
|
+ long chunkNumber = i + 1;
|
|
|
+ int currentChunkSize = part.length;
|
|
|
+ UploadFilePart uploadFilePart = new UploadFilePart(channelId, identifier, filename, relativePath,
|
|
|
+ totalSize, chunkSize, totalChunks, chunkNumber, currentChunkSize);
|
|
|
+ postObject(part, uploadFilePart);
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|