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; |
|||
|
|||
import com.amazonaws.services.s3.model.Bucket; |
|||
import com.amazonaws.services.s3.model.S3ObjectSummary; |
|||
import com.amazonaws.services.s3.AmazonS3Client; |
|||
import com.amazonaws.services.s3.model.*; |
|||
import jakarta.annotation.Resource; |
|||
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 java.io.File; |
|||
import java.io.IOException; |
|||
import java.util.Date; |
|||
import java.util.List; |
|||
import java.util.Map; |
|||
import java.util.concurrent.ConcurrentHashMap; |
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
|
|||
//@Component
|
|||
@Slf4j |
|||
@Component |
|||
@Primary |
|||
public class OSSFileStoreEngine implements StoreEngine { |
|||
@Resource |
|||
private AmazonS3Client amazonS3Client; |
|||
|
|||
// 缓存 bucket 存在性
|
|||
private final Map<String, Boolean> bucketCache = new ConcurrentHashMap<>(); |
|||
|
|||
@Override |
|||
public boolean bucketExists(String bucketName) { |
|||
return false; |
|||
return bucketCache.computeIfAbsent(bucketName, key -> amazonS3Client.doesBucketExistV2(key)); |
|||
} |
|||
|
|||
@Override |
|||
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; |
|||
} |
|||
|
|||
@Override |
|||
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 |
|||
public List<Bucket> getAllBucket() { |
|||
return List.of(); |
|||
return amazonS3Client.listBuckets(); |
|||
} |
|||
|
|||
@Override |
|||
public List<S3ObjectSummary> listObjects(String bucketName) { |
|||
if (bucketExists(bucketName)) { |
|||
return amazonS3Client.listObjects(bucketName).getObjectSummaries(); |
|||
} |
|||
return List.of(); |
|||
} |
|||
|
|||
@Override |
|||
public boolean doesObjectExist(String bucketName, String objectKey) { |
|||
if (bucketExists(bucketName)) { |
|||
return amazonS3Client.doesObjectExist(bucketName, objectKey); |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
@Override |
|||
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; |
|||
} |
|||
|
|||
@Override |
|||
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; |
|||
} |
|||
|
|||
@Override |
|||
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; |
|||
} |
|||
|
|||
@Override |
|||
public String getDownloadUrl(String bucketName, String remoteFileName, long timeout, TimeUnit unit) { |
|||
return ""; |
|||
public String getDownloadUrl(String bucketName, String objectKey, long timeout, TimeUnit unit) { |
|||
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 |
|||
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