|
@@ -0,0 +1,390 @@
|
|
|
+package com.fdkankan.filestorage.aws;
|
|
|
+
|
|
|
+
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
+import cn.hutool.core.io.FileUtil;
|
|
|
+import cn.hutool.core.io.IoUtil;
|
|
|
+import cn.hutool.core.util.StrUtil;
|
|
|
+import com.alibaba.fastjson2.JSON;
|
|
|
+import com.amazonaws.AmazonServiceException;
|
|
|
+import com.amazonaws.SdkClientException;
|
|
|
+import com.amazonaws.services.s3.AmazonS3;
|
|
|
+import com.amazonaws.services.s3.model.*;
|
|
|
+import com.fdkankan.filestorage.Consumer;
|
|
|
+import com.fdkankan.filestorage.InnerUtils;
|
|
|
+import com.fdkankan.filestorage.OssOptions;
|
|
|
+import com.fdkankan.filestorage.properties.AwsProperties;
|
|
|
+import lombok.Getter;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
+import org.springframework.util.Base64Utils;
|
|
|
+
|
|
|
+import java.io.*;
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
+import java.util.ArrayList;
|
|
|
+import java.util.List;
|
|
|
+import java.util.UUID;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+
|
|
|
+/**
|
|
|
+ * 阿里云操作模版类, 简化常见操作
|
|
|
+ */
|
|
|
+@Getter
|
|
|
+@Slf4j
|
|
|
+@Service("AwsOssTemplate")
|
|
|
+@ConditionalOnProperty(prefix = AwsProperties.PREFIX,name = "filestorage.active",havingValue = "awss3")
|
|
|
+public class AwsTemplate implements OssOptions {
|
|
|
+
|
|
|
+ private final AmazonS3 amazonS3Client;
|
|
|
+ private final AwsProperties ossProperties;
|
|
|
+
|
|
|
+ public AwsTemplate(AmazonS3 amazonS3Client, AwsProperties ossProperties) {
|
|
|
+ this.amazonS3Client = amazonS3Client;
|
|
|
+ this.ossProperties = ossProperties;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String uploadFile(String pathKey, String filePath) {
|
|
|
+ return uploadFile(ossProperties.getBucket(), pathKey, filePath);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String uploadFile(String bucket, String pathKey, String filePath) {
|
|
|
+ InnerUtils.checkArgument(bucket != null && bucket.length() > 0, "bucket can't be empty");
|
|
|
+ InnerUtils.checkArgument(pathKey != null && pathKey.length() > 0, "pathKey can't be empty");
|
|
|
+ uploadFileStream(bucket, pathKey, FileUtil.getInputStream(new File(filePath)));
|
|
|
+ return calculateUrl(bucket, pathKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String uploadFileText(String pathKey, String content) {
|
|
|
+ return uploadFileText(ossProperties.getBucket(), pathKey, content);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String uploadFileText(String bucket, String pathKey, String content) {
|
|
|
+ byte[] bytes = content.getBytes(StandardCharsets.UTF_8);
|
|
|
+ return uploadFileBytes(bucket, pathKey, bytes);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String uploadFileBase64Image(String pathKey, String content) {
|
|
|
+ return uploadFileBase64Image(ossProperties.getBucket(), pathKey, content);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String uploadFileBase64Image(String bucket, String pathKey, String content) {
|
|
|
+ byte[] bytes = Base64Utils.decodeFromString(content);
|
|
|
+ return uploadFileBytes(bucket, pathKey, bytes);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String uploadFileBytes(String pathKey, byte[] bytes) {
|
|
|
+ return uploadFileBytes(ossProperties.getBucket(), pathKey, bytes);
|
|
|
+ }
|
|
|
+
|
|
|
+ public void createbucket() {
|
|
|
+ try {
|
|
|
+ if (StrUtil.isEmpty(ossProperties.getBucket())) {
|
|
|
+ throw new IllegalArgumentException("桶名称不能为空!");
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ amazonS3Client.createBucket(ossProperties.getBucket());
|
|
|
+ } catch (SdkClientException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String uploadFileBytes(String bucket, String pathKey, byte[] bytes) {
|
|
|
+ ByteArrayInputStream stream = new ByteArrayInputStream(bytes);
|
|
|
+ return uploadFileStream(bucket, pathKey, stream);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String uploadFileStream(String pathKey, InputStream stream) {
|
|
|
+ return uploadFileStream(ossProperties.getBucket(), pathKey, stream);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String uploadFileStream(String bucket, String pathKey, InputStream stream) {
|
|
|
+
|
|
|
+ InnerUtils.checkArgument(bucket != null && bucket.length() > 0, "bucket can't be empty");
|
|
|
+ InnerUtils.checkArgument(pathKey != null && pathKey.length() > 0, "pathKey can't be empty");
|
|
|
+ InnerUtils.checkArgument(stream != null, "stream can't be null");
|
|
|
+ try {
|
|
|
+ ObjectMetadata metadata = new ObjectMetadata();
|
|
|
+ if (pathKey.contains(".jpg")) {
|
|
|
+ metadata.setContentType("image/jpeg");
|
|
|
+ } else if (pathKey.contains(".png")) {
|
|
|
+ metadata.setContentType("image/png");
|
|
|
+ } else if (pathKey.contains(".json")) {
|
|
|
+ metadata.setContentType("application/json");
|
|
|
+
|
|
|
+ }
|
|
|
+ PutObjectRequest request = new PutObjectRequest(bucket, pathKey,stream ,metadata);
|
|
|
+ request.withCannedAcl(CannedAccessControlList.PublicRead);
|
|
|
+ PutObjectResult putObjectResult = amazonS3Client.putObject(request);
|
|
|
+ if (StrUtil.isNotEmpty(putObjectResult.getETag())) {
|
|
|
+ log.info("s3上传文件成功:" + pathKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ }
|
|
|
+ return calculateUrl(bucket, pathKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public File downloadFileTmp(String pathKey) {
|
|
|
+ return downloadFileTmp(ossProperties.getBucket(), pathKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public File downloadFileTmp(String bucket, String pathKey) {
|
|
|
+ String tmpDir = System.getProperty("java.io.tmpdir");
|
|
|
+ String file = tmpDir + UUID.randomUUID();
|
|
|
+ downloadFile(bucket, pathKey, file);
|
|
|
+ return new File(file);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ObjectMetadata downloadFile(String pathKey, String file) {
|
|
|
+ return downloadFile(ossProperties.getBucket(), pathKey, file);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ObjectMetadata downloadFile(String bucket, String pathKey, String file) {
|
|
|
+ InnerUtils.checkArgument(bucket != null && bucket.length() > 0, "bucket can't be empty");
|
|
|
+ InnerUtils.checkArgument(pathKey != null && pathKey.length() > 0, "pathKey can't be empty");
|
|
|
+ InnerUtils.checkArgument(file != null && file.length() > 0, "file can't be empty");
|
|
|
+ GetObjectRequest request = new GetObjectRequest(bucket,pathKey);
|
|
|
+ log.info("下载开始:下载bucket={},下载pathKey={},下载filePath={}", bucket, pathKey, file);
|
|
|
+ try {
|
|
|
+
|
|
|
+ return amazonS3Client.getObject(request,new File(file));
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ObjectMetadata downloadFile(String pathKey, Consumer<InputStream> handler) {
|
|
|
+ return downloadFile(ossProperties.getBucket(), pathKey, handler);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public ObjectMetadata downloadFile(String bucket, String pathKey, Consumer<InputStream> handler) {
|
|
|
+
|
|
|
+
|
|
|
+ InnerUtils.checkArgument(bucket != null && bucket.length() > 0, "bucket can't be empty");
|
|
|
+ InnerUtils.checkArgument(pathKey != null && pathKey.length() > 0, "pathKey can't be empty");
|
|
|
+ InnerUtils.checkArgument(handler != null, "handler can't be null");
|
|
|
+ GetObjectRequest request = new GetObjectRequest(bucket,pathKey);
|
|
|
+ S3Object object = amazonS3Client.getObject(request);
|
|
|
+ InputStream content = object.getObjectContent();
|
|
|
+ try {
|
|
|
+ handler.accept(content);
|
|
|
+ } finally {
|
|
|
+ if (content != null) {
|
|
|
+ try {
|
|
|
+ content.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ // Ignore
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return object.getObjectMetadata();
|
|
|
+ }
|
|
|
+
|
|
|
+ public String calculateUrl(String pathKey) {
|
|
|
+ return calculateUrl(ossProperties.getBucket(), pathKey);
|
|
|
+ }
|
|
|
+
|
|
|
+ public String calculateUrl(String bucket, String pathKey) {
|
|
|
+ String host = ossProperties.getHostByBucket(bucket);
|
|
|
+ return host + "/" + pathKey;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String calculatePathKey(String url) {
|
|
|
+ String urlPath = InnerUtils.getUrlPath(url);
|
|
|
+ if (urlPath != null && urlPath.startsWith("/")) {
|
|
|
+ String pathKey = urlPath.substring(1);
|
|
|
+ if (pathKey.length() > 0) {
|
|
|
+ return InnerUtils.decodeUrl(pathKey);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ public String calculateHost(String endpoint, String bucket) {
|
|
|
+ return InnerUtils.generateHost(endpoint, bucket);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Boolean copyObject(String oldPath, String newPath) {
|
|
|
+ return copyObject(ossProperties.getBucket(), oldPath, ossProperties.getBucket(), newPath);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public Boolean copyObject(String bucket, String oldPath, String toBucket, String newPath) {
|
|
|
+ try {
|
|
|
+ List<String> sourceKeyList = this.getFileFolder(oldPath);
|
|
|
+
|
|
|
+ // 复制文件
|
|
|
+ sourceKeyList.parallelStream().forEach(key -> {
|
|
|
+ log.info("开始复制:" + key);
|
|
|
+ amazonS3Client.copyObject(bucket, key, toBucket, key.replace(oldPath, newPath));
|
|
|
+ log.info("复制成功:" + key);
|
|
|
+ });
|
|
|
+ CopyObjectResult copyObjectResult = amazonS3Client.copyObject(bucket, oldPath, toBucket, newPath);
|
|
|
+
|
|
|
+ if (StrUtil.isNotBlank(copyObjectResult.getVersionId())) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("文件不存在,KeyName{}", e.getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void deleteObject(String keyName) {
|
|
|
+ if (doesObjectExist(keyName)) {
|
|
|
+ deleteObject(ossProperties.getBucket(), keyName);
|
|
|
+ } else {
|
|
|
+ log.warn("文件不存在,KeyName{}", keyName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void deleteObject(String bucket, String keyName) {
|
|
|
+ try {
|
|
|
+ InnerUtils.checkArgument(bucket != null && bucket.length() > 0, "bucket can't be empty");
|
|
|
+ InnerUtils.checkArgument(keyName != null && keyName.length() > 0, "keyName can't be empty");
|
|
|
+ amazonS3Client.deleteObject(bucket, keyName);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.info("文件删除失败" + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<String> getFileFolder(String keyName) {
|
|
|
+ return getFileFolder(ossProperties.getBucket(), keyName);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<String> getFileFolder(String bucket, String keyName) {
|
|
|
+ List<String> list = new ArrayList<>();
|
|
|
+ try {
|
|
|
+ String nextMaker = null;
|
|
|
+ boolean flag = true;
|
|
|
+ ListObjectsRequest listObjectsRequest = new ListObjectsRequest();
|
|
|
+ listObjectsRequest.setBucketName(bucket);
|
|
|
+ listObjectsRequest.setPrefix(keyName);
|
|
|
+ listObjectsRequest.setMaxKeys(200);
|
|
|
+ do{
|
|
|
+ listObjectsRequest.setMarker(nextMaker);
|
|
|
+ ObjectListing objectListing = amazonS3Client.listObjects(listObjectsRequest);
|
|
|
+ List<S3ObjectSummary> objectSummaries = objectListing.getObjectSummaries();
|
|
|
+ List<String> collect =objectSummaries.stream().map(summary->{
|
|
|
+ return summary.getKey();
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ if(CollUtil.isNotEmpty(collect)){
|
|
|
+ list.addAll(collect);
|
|
|
+ }
|
|
|
+ nextMaker = objectListing.getNextMarker();
|
|
|
+ flag = objectListing.isTruncated();
|
|
|
+ }while (flag);
|
|
|
+ log.info("获取文件夹集合={}", JSON.toJSONString(list));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("获取文件夹集合失败={}", e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean doesObjectExist(String bucket, String keyName) {
|
|
|
+ try {
|
|
|
+ GetObjectRequest request = new GetObjectRequest(bucket,keyName);
|
|
|
+ S3Object object = amazonS3Client.getObject(request);
|
|
|
+ return true;
|
|
|
+ } catch (AmazonServiceException e) {
|
|
|
+ if (e.getErrorCode().equalsIgnoreCase("NoSuchKey")) {
|
|
|
+ log.error("NoSuchKey", e.getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("连接异常", e.getMessage());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ @Override
|
|
|
+ public String getBucket() {
|
|
|
+ return ossProperties.getBucket();
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean ossDownloadFileToLocal(String bucket,String keyName, String localPath) {
|
|
|
+ try {
|
|
|
+ GetObjectRequest request = new GetObjectRequest(bucket,keyName);
|
|
|
+ amazonS3Client.getObject(request,new File(localPath));
|
|
|
+ return true;
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("amazonS3下载文件失败,key=" + amazonS3Client, e);
|
|
|
+ }finally {
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean ossDownloadFileToLocal(String path, String localPath) {
|
|
|
+ return ossDownloadFileToLocal(ossProperties.getBucket(),path,localPath);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean doesObjectExist(String keyName) {
|
|
|
+ return doesObjectExist(ossProperties.getBucket(), keyName);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String uploadFileImage(String pathKey, String filePath) {
|
|
|
+ return uploadFileImage(ossProperties.getBucket(), pathKey, filePath);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String uploadFileImage(String bucket, String pathKey, String filePath) {
|
|
|
+ InputStream stream = null;
|
|
|
+ try {
|
|
|
+ ObjectMetadata metadata = new ObjectMetadata();
|
|
|
+ if (pathKey.contains(".jpg")) {
|
|
|
+ metadata.setContentType("image/jpeg");
|
|
|
+ } else if (pathKey.contains(".png")) {
|
|
|
+ metadata.setContentType("image/png");
|
|
|
+ } else if (pathKey.contains(".json")) {
|
|
|
+ metadata.setContentType("application/json");
|
|
|
+ }
|
|
|
+ stream = FileUtil.getInputStream(new File(filePath));
|
|
|
+ PutObjectRequest request = new PutObjectRequest(bucket, pathKey,stream ,metadata);
|
|
|
+ request.withCannedAcl(CannedAccessControlList.PublicRead);
|
|
|
+ PutObjectResult putObjectResult = amazonS3Client.putObject(request);
|
|
|
+ } catch (Exception e) {
|
|
|
+ return "";
|
|
|
+ } finally {
|
|
|
+ IoUtil.close(stream);
|
|
|
+ }
|
|
|
+ return calculateUrl(bucket, pathKey);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+}
|