|
@@ -0,0 +1,196 @@
|
|
|
+package cn.com.qmth.examcloud.support.fss.impl;
|
|
|
+
|
|
|
+import cn.com.qmth.examcloud.commons.exception.StatusException;
|
|
|
+import cn.com.qmth.examcloud.support.fss.FssHelper;
|
|
|
+import cn.com.qmth.examcloud.support.fss.FssProperty;
|
|
|
+import cn.com.qmth.examcloud.support.fss.FssService;
|
|
|
+import cn.com.qmth.examcloud.support.fss.model.FileInfo;
|
|
|
+import com.aliyun.oss.OSS;
|
|
|
+import com.aliyun.oss.OSSClientBuilder;
|
|
|
+import com.aliyun.oss.model.GetObjectRequest;
|
|
|
+import com.aliyun.oss.model.OSSObject;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import java.io.ByteArrayInputStream;
|
|
|
+import java.io.ByteArrayOutputStream;
|
|
|
+import java.io.File;
|
|
|
+import java.io.InputStream;
|
|
|
+
|
|
|
+public class AliyunOssService implements FssService {
|
|
|
+
|
|
|
+ private static final Logger log = LoggerFactory.getLogger(AliyunOssService.class);
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 是否内网访问
|
|
|
+ */
|
|
|
+ private boolean internal;
|
|
|
+
|
|
|
+ public AliyunOssService setInternal(boolean internal) {
|
|
|
+ this.internal = internal;
|
|
|
+ return this;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public FileInfo writeFile(String filePath, File file, String md5) {
|
|
|
+ if (StringUtils.isEmpty(md5)) {
|
|
|
+ throw new StatusException("文件MD5值不能为空!");
|
|
|
+ }
|
|
|
+
|
|
|
+ String realMd5 = FssHelper.getFileMD5(file);
|
|
|
+ if (!realMd5.equals(md5)) {
|
|
|
+ log.warn("filePath:{} realMD5:{} MD5:{}", filePath, realMd5, md5);
|
|
|
+ throw new StatusException("文件MD5值校验不通过!");
|
|
|
+ }
|
|
|
+
|
|
|
+ filePath = this.fixOssFilePath(filePath);
|
|
|
+ OSS ossClient = this.getClient();
|
|
|
+
|
|
|
+ try {
|
|
|
+ ossClient.putObject(FssProperty.FSS_BUCKET, filePath, file);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("文件上传失败!filePath:{} err:{}", filePath, e.getMessage());
|
|
|
+ throw new StatusException("文件上传失败!");
|
|
|
+ } finally {
|
|
|
+ try {
|
|
|
+ ossClient.shutdown();
|
|
|
+ } catch (Exception e) {
|
|
|
+ // ignore
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ filePath = FssProperty.FSS_SEPARATOR + filePath;
|
|
|
+ FileInfo result = new FileInfo();
|
|
|
+ result.setFileName(FssHelper.getFileName(filePath));
|
|
|
+ result.setFilePath(filePath);
|
|
|
+ result.setFileUrl(FssProperty.FSS_URL_PREFIX + filePath);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public FileInfo writeFile(String filePath, byte[] bytes, String md5) {
|
|
|
+ if (StringUtils.isEmpty(md5)) {
|
|
|
+ throw new StatusException("文件MD5值不能为空!");
|
|
|
+ }
|
|
|
+
|
|
|
+ String realMd5 = FssHelper.getFileMD5(bytes);
|
|
|
+ if (!realMd5.equals(md5)) {
|
|
|
+ log.warn("filePath:{} realMD5:{} MD5:{}", filePath, realMd5, md5);
|
|
|
+ throw new StatusException("文件MD5值校验不通过!");
|
|
|
+ }
|
|
|
+
|
|
|
+ filePath = this.fixOssFilePath(filePath);
|
|
|
+ OSS ossClient = this.getClient();
|
|
|
+
|
|
|
+ try (ByteArrayInputStream is = new ByteArrayInputStream(bytes);) {
|
|
|
+ ossClient.putObject(FssProperty.FSS_BUCKET, filePath, is);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("文件上传失败!filePath:{} err:{}", filePath, e.getMessage());
|
|
|
+ throw new StatusException("文件上传失败!");
|
|
|
+ } finally {
|
|
|
+ try {
|
|
|
+ ossClient.shutdown();
|
|
|
+ } catch (Exception e) {
|
|
|
+ // ignore
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ filePath = FssProperty.FSS_SEPARATOR + filePath;
|
|
|
+ FileInfo result = new FileInfo();
|
|
|
+ result.setFileName(FssHelper.getFileName(filePath));
|
|
|
+ result.setFilePath(filePath);
|
|
|
+ result.setFileUrl(FssProperty.FSS_URL_PREFIX + filePath);
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void readFile(String filePath, File toFile) {
|
|
|
+ filePath = this.fixOssFilePath(filePath);
|
|
|
+ OSS ossClient = this.getClient();
|
|
|
+
|
|
|
+ try {
|
|
|
+ GetObjectRequest request = new GetObjectRequest(FssProperty.FSS_BUCKET, filePath);
|
|
|
+
|
|
|
+ FssHelper.makeDirs(toFile.getParent());
|
|
|
+ ossClient.getObject(request, toFile);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("文件下载失败!filePath:{} err:{}", filePath, e.getMessage());
|
|
|
+ throw new StatusException("文件下载失败!");
|
|
|
+ } finally {
|
|
|
+ try {
|
|
|
+ ossClient.shutdown();
|
|
|
+ } catch (Exception e) {
|
|
|
+ // ignore
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public byte[] readFile(String filePath) {
|
|
|
+ filePath = this.fixOssFilePath(filePath);
|
|
|
+ OSS ossClient = this.getClient();
|
|
|
+
|
|
|
+ InputStream is = null;
|
|
|
+ ByteArrayOutputStream bos = null;
|
|
|
+ try {
|
|
|
+ OSSObject ossObject = ossClient.getObject(FssProperty.FSS_BUCKET, filePath);
|
|
|
+ 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("文件下载失败!filePath:{} err:{}", filePath, e.getMessage());
|
|
|
+ throw new StatusException("文件下载失败!");
|
|
|
+ } finally {
|
|
|
+ try {
|
|
|
+ if (is != null) {
|
|
|
+ is.close();
|
|
|
+ }
|
|
|
+ if (bos != null) {
|
|
|
+ bos.close();
|
|
|
+ }
|
|
|
+
|
|
|
+ ossClient.shutdown();
|
|
|
+ } catch (Exception e) {
|
|
|
+ // ignore
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private OSS getClient() {
|
|
|
+ try {
|
|
|
+ // ClientBuilderConfiguration configuration = new ClientBuilderConfiguration();
|
|
|
+ OSS ossClient = new OSSClientBuilder().build(
|
|
|
+ internal ? FssProperty.FSS_INTERNAL_ENDPOINT : FssProperty.FSS_ENDPOINT,
|
|
|
+ FssProperty.FSS_ACCESS_KEY_ID, FssProperty.FSS_ACCESS_KEY_SECRET);
|
|
|
+ // ossClient.setBucketTransferAcceleration(FssProperty.FSS_BUCKET, internal);
|
|
|
+ return ossClient;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ throw new StatusException("OSS客户端初始化失败!");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private String fixOssFilePath(String ossFilePath) {
|
|
|
+ if (StringUtils.isEmpty(ossFilePath)) {
|
|
|
+ throw new StatusException("文件存储路径不能为空!");
|
|
|
+ }
|
|
|
+
|
|
|
+ // OSS存储路径不允许以 / 开头,需要去掉 /
|
|
|
+ if (ossFilePath.startsWith("/")) {
|
|
|
+ return ossFilePath.substring(1);
|
|
|
+ }
|
|
|
+
|
|
|
+ return ossFilePath;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|