6 changed files with 6378 additions and 23 deletions
File diff suppressed because it is too large
@ -1,68 +1,160 @@ |
|||||
package org.ycloud.aipan.component; |
package org.ycloud.aipan.component; |
||||
|
|
||||
import com.amazonaws.services.s3.model.Bucket; |
import com.amazonaws.services.s3.AmazonS3Client; |
||||
import com.amazonaws.services.s3.model.S3ObjectSummary; |
import com.amazonaws.services.s3.model.*; |
||||
|
import jakarta.annotation.Resource; |
||||
import jakarta.servlet.http.HttpServletResponse; |
import jakarta.servlet.http.HttpServletResponse; |
||||
|
import lombok.extern.slf4j.Slf4j; |
||||
|
import org.apache.tomcat.util.http.fileupload.IOUtils; |
||||
|
import org.springframework.context.annotation.Primary; |
||||
|
import org.springframework.stereotype.Component; |
||||
import org.springframework.web.multipart.MultipartFile; |
import org.springframework.web.multipart.MultipartFile; |
||||
|
|
||||
|
import java.io.File; |
||||
|
import java.io.IOException; |
||||
|
import java.util.Date; |
||||
import java.util.List; |
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||
import java.util.concurrent.TimeUnit; |
import java.util.concurrent.TimeUnit; |
||||
|
|
||||
|
@Slf4j |
||||
|
@Component |
||||
|
@Primary |
||||
|
public class OSSFileStoreEngine implements StoreEngine { |
||||
|
@Resource |
||||
|
private AmazonS3Client amazonS3Client; |
||||
|
|
||||
|
// 缓存 bucket 存在性
|
||||
|
private final Map<String, Boolean> bucketCache = new ConcurrentHashMap<>(); |
||||
|
|
||||
//@Component
|
|
||||
public class OSSFileStoreEngine implements StoreEngine{ |
|
||||
@Override |
@Override |
||||
public boolean bucketExists(String bucketName) { |
public boolean bucketExists(String bucketName) { |
||||
return false; |
return bucketCache.computeIfAbsent(bucketName, key -> amazonS3Client.doesBucketExistV2(key)); |
||||
} |
} |
||||
|
|
||||
@Override |
@Override |
||||
public boolean removeBucket(String bucketName) { |
public boolean removeBucket(String bucketName) { |
||||
|
if (bucketExists(bucketName)) { |
||||
|
try { |
||||
|
amazonS3Client.deleteBucket(bucketName); |
||||
|
bucketCache.remove(bucketName); |
||||
|
return true; |
||||
|
} catch (Exception e) { |
||||
|
log.error("删除 bucket {} 失败: {}", bucketName, e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
return false; |
return false; |
||||
} |
} |
||||
|
|
||||
@Override |
@Override |
||||
public void createBucket(String bucketName) { |
public void createBucket(String bucketName) { |
||||
|
log.info("创建 bucket: {}", bucketName); |
||||
|
if (!bucketExists(bucketName)) { |
||||
|
try { |
||||
|
amazonS3Client.createBucket(bucketName); |
||||
|
bucketCache.put(bucketName, true); |
||||
|
} catch (Exception e) { |
||||
|
log.error("创建 bucket {} 失败: {}", bucketName, e.getMessage(), e); |
||||
|
} |
||||
|
} else { |
||||
|
log.info("bucket 已存在"); |
||||
|
} |
||||
} |
} |
||||
|
|
||||
@Override |
@Override |
||||
public List<Bucket> getAllBucket() { |
public List<Bucket> getAllBucket() { |
||||
return List.of(); |
return amazonS3Client.listBuckets(); |
||||
} |
} |
||||
|
|
||||
@Override |
@Override |
||||
public List<S3ObjectSummary> listObjects(String bucketName) { |
public List<S3ObjectSummary> listObjects(String bucketName) { |
||||
|
if (bucketExists(bucketName)) { |
||||
|
return amazonS3Client.listObjects(bucketName).getObjectSummaries(); |
||||
|
} |
||||
return List.of(); |
return List.of(); |
||||
} |
} |
||||
|
|
||||
@Override |
@Override |
||||
public boolean doesObjectExist(String bucketName, String objectKey) { |
public boolean doesObjectExist(String bucketName, String objectKey) { |
||||
|
if (bucketExists(bucketName)) { |
||||
|
return amazonS3Client.doesObjectExist(bucketName, objectKey); |
||||
|
} |
||||
return false; |
return false; |
||||
} |
} |
||||
|
|
||||
@Override |
@Override |
||||
public boolean upload(String bucketName, String objectKey, String localFileName) { |
public boolean upload(String bucketName, String objectKey, String localFileName) { |
||||
|
if (bucketExists(bucketName)) { |
||||
|
try { |
||||
|
amazonS3Client.putObject(bucketName, objectKey, new File(localFileName)); |
||||
|
return true; |
||||
|
} catch (Exception e) { |
||||
|
log.error("上传文件到 bucket {} 失败: {}", bucketName, e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
return false; |
return false; |
||||
} |
} |
||||
|
|
||||
@Override |
@Override |
||||
public boolean upload(String bucketName, String objectKey, MultipartFile file) { |
public boolean upload(String bucketName, String objectKey, MultipartFile file) { |
||||
|
if (bucketExists(bucketName)) { |
||||
|
try { |
||||
|
ObjectMetadata objectMetadata = new ObjectMetadata(); |
||||
|
objectMetadata.setContentType(file.getContentType()); |
||||
|
objectMetadata.setContentLength(file.getSize()); |
||||
|
amazonS3Client.putObject(bucketName, objectKey, file.getInputStream(), objectMetadata); |
||||
|
return true; |
||||
|
} catch (Exception e) { |
||||
|
log.error("上传文件到 bucket {} 失败: {}", bucketName, e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
return false; |
return false; |
||||
} |
} |
||||
|
|
||||
@Override |
@Override |
||||
public boolean delete(String bucketName, String objectKey) { |
public boolean delete(String bucketName, String objectKey) { |
||||
|
if (bucketExists(bucketName)) { |
||||
|
try { |
||||
|
amazonS3Client.deleteObject(bucketName, objectKey); |
||||
|
return true; |
||||
|
} catch (Exception e) { |
||||
|
log.error("删除 bucket {} 中的对象 {} 失败: {}", bucketName, objectKey, e.getMessage(), e); |
||||
|
} |
||||
|
} |
||||
return false; |
return false; |
||||
} |
} |
||||
|
|
||||
@Override |
@Override |
||||
public String getDownloadUrl(String bucketName, String remoteFileName, long timeout, TimeUnit unit) { |
public String getDownloadUrl(String bucketName, String objectKey, long timeout, TimeUnit unit) { |
||||
return ""; |
try { |
||||
|
Date expiration = new Date(System.currentTimeMillis() + unit.toMillis(timeout)); |
||||
|
return amazonS3Client.generatePresignedUrl(bucketName, objectKey, expiration).toString(); |
||||
|
} catch (Exception e) { |
||||
|
log.error("生成 bucket {} 中对象 {} 的下载 URL 失败: {}", bucketName, objectKey, e.getMessage(), e); |
||||
|
return null; |
||||
|
} |
||||
} |
} |
||||
|
|
||||
@Override |
@Override |
||||
public void download2Response(String bucketName, String objectKey, HttpServletResponse response) { |
public void download2Response(String bucketName, String objectKey, HttpServletResponse response) { |
||||
|
try (S3Object s3Object = amazonS3Client.getObject(bucketName, objectKey)) { |
||||
|
response.setHeader("Content-Disposition", "attachment;filename=" + objectKey.substring(objectKey.lastIndexOf("/") + 1)); |
||||
|
response.setContentType("application/force-download"); |
||||
|
response.setCharacterEncoding("UTF-8"); |
||||
|
IOUtils.copy(s3Object.getObjectContent(), response.getOutputStream()); |
||||
|
} catch (IOException e) { |
||||
|
log.error("下载 bucket {} 中对象 {} 失败: {}", bucketName, objectKey, e.getMessage(), e); |
||||
} |
} |
||||
|
} |
||||
|
|
||||
|
// 拼接路径
|
||||
|
// public static void main(String[] args) {
|
||||
|
// String fileSeparator = System.getProperty("file.separator");
|
||||
|
// System.out.println("dir" + fileSeparator + "time" + fileSeparator + "index.html");
|
||||
|
// String files = String.join("/", List.of("dir", "time", "index.html"));
|
||||
|
// System.out.println(files);
|
||||
|
// Path file = Paths.get("dir", "time", "index.html");
|
||||
|
// System.out.println(file);
|
||||
|
// }
|
||||
} |
} |
@ -0,0 +1,28 @@ |
|||||
|
package org.ycloud.aipan.config; |
||||
|
|
||||
|
import lombok.Data; |
||||
|
import org.springframework.beans.factory.annotation.Value; |
||||
|
import org.springframework.boot.context.properties.ConfigurationProperties; |
||||
|
import org.springframework.stereotype.Component; |
||||
|
|
||||
|
@Data |
||||
|
@Component |
||||
|
@ConfigurationProperties(prefix = "oss") |
||||
|
public class AliOssConfig { |
||||
|
|
||||
|
@Value("endpoint") |
||||
|
private String endpoint; |
||||
|
|
||||
|
@Value("access-key") |
||||
|
private String accessKey; |
||||
|
|
||||
|
@Value("access-secret") |
||||
|
private String accessSecret; |
||||
|
|
||||
|
@Value("bucket-name") |
||||
|
private String bucketName; |
||||
|
|
||||
|
|
||||
|
// 预签名url过期时间(ms)
|
||||
|
private Long PRE_SIGN_URL_EXPIRE = 60 * 10 * 1000L; |
||||
|
} |
Loading…
Reference in new issue