deason 3 weeks ago
parent
commit
5ef28261d1

+ 6 - 0
pom.xml

@@ -79,6 +79,12 @@
             <version>1.17.2</version>
         </dependency>
 
+        <dependency>
+            <groupId>com.aliyun.oss</groupId>
+            <artifactId>aliyun-sdk-oss</artifactId>
+            <version>3.17.4</version>
+        </dependency>
+
         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-test</artifactId>

+ 24 - 0
src/main/java/cn/com/qmth/examcloud/tool/utils/oss/OssConfig.java

@@ -0,0 +1,24 @@
+package cn.com.qmth.examcloud.tool.utils.oss;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class OssConfig {
+
+    public final static String SEPARATOR = "/";
+
+    private String bucket;
+
+    private String regionId;
+
+    private String endpoint;
+
+    private String accessKeyId;
+
+    private String accessKeySecret;
+
+    private String urlPrefix;
+
+}

+ 16 - 0
src/main/java/cn/com/qmth/examcloud/tool/utils/oss/OssFileInfo.java

@@ -0,0 +1,16 @@
+package cn.com.qmth.examcloud.tool.utils.oss;
+
+import lombok.Getter;
+import lombok.Setter;
+
+@Setter
+@Getter
+public class OssFileInfo {
+
+    private String fileName;
+
+    private String filePath;
+
+    private String fileUrl;
+
+}

+ 75 - 0
src/main/java/cn/com/qmth/examcloud/tool/utils/oss/OssHelper.java

@@ -0,0 +1,75 @@
+package cn.com.qmth.examcloud.tool.utils.oss;
+
+import cn.com.qmth.examcloud.tool.utils.FileHelper;
+import cn.com.qmth.examcloud.tool.utils.StatusException;
+import com.aliyun.oss.ClientBuilderConfiguration;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import org.apache.commons.lang3.StringUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+
+public class OssHelper {
+
+    private final static Logger log = LoggerFactory.getLogger(OssHelper.class);
+
+    private OssConfig config;
+
+    public OssHelper(OssConfig config) {
+        this.config = config;
+    }
+
+    public OssFileInfo writeFile(String filePath, File file) {
+        filePath = fixOssFilePath(filePath);
+        OSS client = getClient(config);
+        try {
+            client.putObject(config.getBucket(), filePath, file);
+        } catch (Exception e) {
+            log.error("文件上传失败!filePath:{} err:{}", filePath, e.getMessage());
+            throw new StatusException("文件上传失败!");
+        } finally {
+            try {
+                client.shutdown();
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+
+        filePath = OssConfig.SEPARATOR + filePath;
+        OssFileInfo result = new OssFileInfo();
+        result.setFileName(FileHelper.getFileName(filePath));
+        result.setFilePath(filePath);
+        result.setFileUrl(config.getUrlPrefix() + filePath);
+        return result;
+    }
+
+    private OSS getClient(OssConfig config) {
+        try {
+            ClientBuilderConfiguration configuration = new ClientBuilderConfiguration();
+            configuration.setMaxErrorRetry(1);
+
+            OSS client = new OSSClientBuilder().build(config.getEndpoint(),
+                    config.getAccessKeyId(), config.getAccessKeySecret(), configuration);
+            // client.setBucketTransferAcceleration(config.getBucket(), true);
+            return client;
+        } catch (Exception e) {
+            log.error(e.getMessage(), e);
+            throw new StatusException("OSS客户端初始化失败!");
+        }
+    }
+
+    private String fixOssFilePath(String filePath) {
+        if (StringUtils.isEmpty(filePath)) {
+            throw new StatusException("文件存储路径不能为空!");
+        }
+
+        // OSS存储路径不允许以 / 开头,需要去掉 /
+        if (filePath.startsWith("/")) {
+            return filePath.substring(1);
+        }
+        return filePath;
+    }
+
+}

+ 79 - 0
src/test/java/cn/com/qmth/examcloud/tool/UploadTest.java

@@ -0,0 +1,79 @@
+package cn.com.qmth.examcloud.tool;
+
+import ch.qos.logback.classic.LoggerContext;
+import cn.com.qmth.examcloud.tool.utils.oss.OssConfig;
+import cn.com.qmth.examcloud.tool.utils.oss.OssFileInfo;
+import cn.com.qmth.examcloud.tool.utils.oss.OssHelper;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.atomic.AtomicInteger;
+
+public class UploadTest {
+
+    private final static Logger log = LoggerFactory.getLogger(UploadTest.class);
+
+    @Before
+    public void init() throws Exception {
+        // Configurator.setRootLevel(Level.INFO);
+        LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
+        ch.qos.logback.classic.Logger logger = loggerContext.getLogger("org.apache");
+        logger.setLevel(ch.qos.logback.classic.Level.INFO);
+        ch.qos.logback.classic.Logger logger2 = loggerContext.getLogger("com.aliyun");
+        logger2.setLevel(ch.qos.logback.classic.Level.INFO);
+    }
+
+    @Test
+    public void demo() throws Exception {
+        OssConfig ossConfig = new OssConfig();
+        ossConfig.setBucket("apply-file");
+        ossConfig.setRegionId("oss-cn-shenzhen");
+        ossConfig.setEndpoint("https://oss-cn-shenzhen.aliyuncs.com");
+        ossConfig.setAccessKeyId("xxx");
+        ossConfig.setAccessKeySecret("xxx");
+        ossConfig.setUrlPrefix("https://apply-file.qmth.com.cn");
+
+        File dir = new File(ToolTest.DATA_DIR + "/17068-250528/test");
+        File[] files = dir.listFiles();
+
+        long startTime = System.currentTimeMillis();
+        AtomicInteger finishAc = new AtomicInteger(), successAc = new AtomicInteger(), failAc = new AtomicInteger();
+        ExecutorService executorService = Executors.newFixedThreadPool(10);
+
+        final int totalCount = files.length;
+        for (File file : files) {
+            executorService.execute(() -> {
+                try {
+                    OssFileInfo result = new OssHelper(ossConfig).writeFile(file.getName(), file);
+                    int successCount = successAc.incrementAndGet();
+                    log.debug("{} -> {} {}", successCount, result.getFileName(), result.getFileUrl());
+                } catch (Exception e) {
+                    log.error("【图片上传】 {} err:{}", file.getName(), e.getMessage());
+                    failAc.incrementAndGet();
+                }
+
+                int finishCount = finishAc.incrementAndGet();
+                if (finishCount % 100 == 0) {
+                    float finishRate = finishCount * 100f / totalCount;
+                    long cost = Math.max((System.currentTimeMillis() - startTime) / 1000, 1);
+                    float speed = (float) finishCount / cost;
+                    log.info("【图片上传】 总数:{} 成功数:{} 失败数:{} 进度:{}% 速度:约{}个每秒 已耗时:{}秒",
+                            totalCount, successAc.get(), failAc.get(), finishRate, speed, cost);
+                }
+            });
+        }
+
+        executorService.shutdown();
+        while (!executorService.isTerminated()) {
+            // ignore
+        }
+
+        log.info("文件上传已完成!");
+    }
+
+}