deason 2 år sedan
förälder
incheckning
15c50a2e07

+ 5 - 0
examcloud-support/pom.xml

@@ -22,6 +22,11 @@
             <artifactId>examcloud-question-commons</artifactId>
             <version>${project.version}</version>
         </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
 </project>

+ 47 - 0
examcloud-support/src/test/java/cn/com/qmth/examcloud/support/test/OssClientTest.java

@@ -0,0 +1,47 @@
+package cn.com.qmth.examcloud.support.test;
+
+import cn.com.qmth.examcloud.commons.util.FileUtil;
+import cn.com.qmth.examcloud.web.aliyun.OssClient;
+import cn.com.qmth.examcloud.web.config.SystemProperties;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.core.config.Configurator;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+
+public class OssClientTest {
+
+    @Before
+    public void init() {
+        Configurator.setRootLevel(Level.INFO);
+    }
+
+    @Test
+    public void demoTest() {
+        SystemProperties properties = new SystemProperties();
+        properties.setAliyunBucketName("examcloud-test");
+        // properties.setAliyunOssEndpoint("https://oss-cn-shenzhen-internal.aliyuncs.com");
+        properties.setAliyunOssEndpoint("https://oss-cn-shenzhen.aliyuncs.com");
+        properties.setAliyunDomain("https://ecs-test-static.qmth.com.cn");
+        properties.setAccessKeyId("LTAI4FboXLCJzrjVo5dUoXaU");
+        properties.setAccessKeySecret("O0my6eSAl1Ic62WvxEf3WlMXox1LNX");
+
+        OssClient ossClient = new OssClient();
+        ossClient.setProperties(properties);
+
+        final String dir = "D:/home/test";
+        File file = new File(dir + "/abc.png");
+
+        final String ossFilePath = "/test/abc.png";
+        // ossClient.upload(file, ossFilePath, false);
+        // System.out.println(ossClient.getProperties().getAliyunDomain() + ossFilePath);
+
+        File toFile = new File(dir + "/abc-new.png");
+        // ossClient.download(ossFilePath, toFile);
+
+        byte[] bytes = ossClient.download(ossFilePath);
+        FileUtil.saveToFile(bytes, toFile);
+    }
+
+}

+ 199 - 0
examcloud-web/src/main/java/cn/com/qmth/examcloud/web/aliyun/OssClient.java

@@ -0,0 +1,199 @@
+package cn.com.qmth.examcloud.web.aliyun;
+
+import cn.com.qmth.examcloud.commons.exception.StatusException;
+import cn.com.qmth.examcloud.web.config.SystemProperties;
+import com.aliyun.oss.ClientBuilderConfiguration;
+import com.aliyun.oss.OSS;
+import com.aliyun.oss.OSSClientBuilder;
+import com.aliyun.oss.model.GetObjectRequest;
+import com.aliyun.oss.model.OSSObject;
+import com.aliyuncs.DefaultAcsClient;
+import com.aliyuncs.IAcsClient;
+import com.aliyuncs.cdn.model.v20180510.RefreshObjectCachesRequest;
+import com.aliyuncs.cdn.model.v20180510.RefreshObjectCachesResponse;
+import com.aliyuncs.profile.DefaultProfile;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.InputStream;
+
+@Component
+public class OssClient {
+
+    private static final Logger log = LoggerFactory.getLogger(OssClient.class);
+
+    @Autowired
+    private SystemProperties properties;
+
+    public void upload(File file, String ossFilePath) {
+        this.upload(file, ossFilePath, false);
+    }
+
+    public void upload(File file, String ossFilePath, boolean refreshCDNCache) {
+        OSS ossClient = this.getClient();
+        ossFilePath = this.fixOssFilePath(ossFilePath);
+
+        try {
+            // ObjectMetadata meta = new ObjectMetadata();
+            // meta.setContentMD5(md5);
+            ossClient.putObject(properties.getAliyunBucketName(), ossFilePath, file);
+
+            if (refreshCDNCache) {
+                this.refreshCDNCache(properties.getAliyunDomain() + "/" + ossFilePath);
+            }
+        } catch (Exception e) {
+            log.error("OSS文件上传异常!{}", e.getMessage());
+            throw new StatusException("OSS文件上传异常!");
+        } finally {
+            try {
+                ossClient.shutdown();
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+    }
+
+    public void upload(byte[] fileBytes, String ossFilePath) {
+        this.upload(fileBytes, ossFilePath, false);
+    }
+
+    public void upload(byte[] fileBytes, String ossFilePath, boolean refreshCDNCache) {
+        OSS ossClient = this.getClient();
+        ossFilePath = this.fixOssFilePath(ossFilePath);
+
+        try (ByteArrayInputStream input = new ByteArrayInputStream(fileBytes);) {
+            ossClient.putObject(properties.getAliyunBucketName(), ossFilePath, input);
+
+            if (refreshCDNCache) {
+                this.refreshCDNCache(properties.getAliyunDomain() + "/" + ossFilePath);
+            }
+        } catch (Exception e) {
+            log.error("OSS文件上传异常!{}", e.getMessage());
+            throw new StatusException("OSS文件上传异常!");
+        } finally {
+            try {
+                ossClient.shutdown();
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+    }
+
+    public void download(String ossFilePath, File toFile) {
+        OSS ossClient = this.getClient();
+        ossFilePath = this.fixOssFilePath(ossFilePath);
+
+        try {
+            GetObjectRequest request = new GetObjectRequest(properties.getAliyunBucketName(), ossFilePath);
+            ossClient.getObject(request, toFile);
+        } catch (Exception e) {
+            log.error("OSS文件下载异常!{}", e.getMessage());
+            throw new StatusException("OSS文件下载异常!");
+        } finally {
+            try {
+                ossClient.shutdown();
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+    }
+
+    public byte[] download(String ossFilePath) {
+        OSS ossClient = this.getClient();
+        ossFilePath = this.fixOssFilePath(ossFilePath);
+
+        InputStream is = null;
+        ByteArrayOutputStream bos = null;
+        try {
+            GetObjectRequest request = new GetObjectRequest(properties.getAliyunBucketName(), ossFilePath);
+            OSSObject ossObject = ossClient.getObject(request);
+
+            is = ossObject.getObjectContent();
+            bos = new ByteArrayOutputStream();
+
+            int len;
+            byte[] bytes = new byte[1024];
+            while ((len = is.read(bytes)) != -1) {
+                bos.write(bytes, 0, len);
+            }
+            bos.flush();
+            ossObject.close();
+
+            return bos.toByteArray();
+        } catch (Exception e) {
+            log.error("OSS文件下载异常!{}", e.getMessage());
+            throw new StatusException("OSS文件下载异常!");
+        } finally {
+            try {
+                ossClient.shutdown();
+                if (is != null) {
+                    is.close();
+                }
+                if (bos != null) {
+                    bos.close();
+                }
+            } catch (Exception e) {
+                // ignore
+            }
+        }
+    }
+
+    /**
+     * 刷新文件的CDN缓存:
+     * 1、同一个账号 每天最多可提交2000条URL刷新和100个目录刷新
+     * 2、每次请求最多只能提交1000条URL刷新,多个URL之间需要用换行符 \n 分割
+     * 3、每秒最多50次请求
+     */
+    public void refreshCDNCache(String ossFileUrls) {
+        DefaultProfile profile = DefaultProfile.getProfile("oss-cn-shenzhen",
+                properties.getAccessKeyId(), properties.getAccessKeySecret());
+        IAcsClient client = new DefaultAcsClient(profile);
+
+        RefreshObjectCachesRequest request = new RefreshObjectCachesRequest();
+        request.setObjectPath(ossFileUrls);
+        request.setObjectType("file");
+
+        try {
+            RefreshObjectCachesResponse resp = client.getAcsResponse(request);
+
+            log.info("refreshCDNCache:{} RequestId:{}", ossFileUrls, resp != null ? resp.getRequestId() : "none");
+        } catch (Exception e) {
+            log.error("refreshCDNCache:{} err:{}", ossFileUrls, e.getMessage());
+        }
+    }
+
+    private String fixOssFilePath(String ossFilePath) {
+        // OSS file path must be not start with '/'
+        if (ossFilePath.startsWith("/")) {
+            return ossFilePath.substring(1);
+        }
+
+        return ossFilePath;
+    }
+
+    public OSS getClient() {
+        ClientBuilderConfiguration configuration = new ClientBuilderConfiguration();
+
+        OSS client = new OSSClientBuilder().build(
+                properties.getAliyunOssEndpoint(),
+                properties.getAccessKeyId(),
+                properties.getAccessKeySecret(),
+                configuration
+        );
+        return client;
+    }
+
+    public SystemProperties getProperties() {
+        return properties;
+    }
+
+    public void setProperties(SystemProperties properties) {
+        this.properties = properties;
+    }
+
+}

+ 22 - 0
examcloud-web/src/main/java/cn/com/qmth/examcloud/web/config/SystemProperties.java

@@ -52,6 +52,12 @@ public class SystemProperties {
     @Value("${$aliyun.site.1.domain}")
     private String aliyunDomain;
 
+    @Value("${$aliyun.site.1.accessKeyId}")
+    private String accessKeyId;
+
+    @Value("${$aliyun.site.1.accessKeySecret}")
+    private String accessKeySecret;
+
     /**
      * 应用ID
      */
@@ -131,6 +137,22 @@ public class SystemProperties {
         this.aliyunDomain = aliyunDomain;
     }
 
+    public String getAccessKeyId() {
+        return accessKeyId;
+    }
+
+    public void setAccessKeyId(String accessKeyId) {
+        this.accessKeyId = accessKeyId;
+    }
+
+    public String getAccessKeySecret() {
+        return accessKeySecret;
+    }
+
+    public void setAccessKeySecret(String accessKeySecret) {
+        this.accessKeySecret = accessKeySecret;
+    }
+
     /**
      * 将文件存储环境的 公网域名 替换为 阿里云内网域名
      */