处理下载为公共模块
This commit is contained in:
+27
-22
@@ -10,9 +10,8 @@ import org.springframework.stereotype.Service;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
import java.util.Objects;
|
||||
import java.util.UUID;
|
||||
|
||||
@@ -23,8 +22,8 @@ public class OssStorageService {
|
||||
private final OssProperties ossProperties;
|
||||
|
||||
/**
|
||||
* 上传结果文件到 OSS,返回 objectKey(非预签名 URL)。
|
||||
* 调用方应存储 objectKey,下载时通过 generateFreshDownloadUrl 按需生成链接。
|
||||
* 上传结果文件到 OSS,返回 objectKey。
|
||||
* 调用方应存储 objectKey,下载时通过 generateFreshDownloadUrl 生成公开直链。
|
||||
*/
|
||||
public String uploadResultFile(File file, String moduleType) {
|
||||
String objectKey = String.format("result/%s/%s/%s", moduleType.toLowerCase(), UUID.randomUUID(), file.getName());
|
||||
@@ -42,9 +41,7 @@ public class OssStorageService {
|
||||
OSS ossClient = buildClient();
|
||||
try {
|
||||
ossClient.putObject(ossProperties.getBucket(), objectKey, file);
|
||||
Date expiration = new Date(System.currentTimeMillis() + 3600_000L);
|
||||
URL url = ossClient.generatePresignedUrl(ossProperties.getBucket(), objectKey, expiration);
|
||||
return new UploadedResult(objectKey, url.toString());
|
||||
return new UploadedResult(objectKey, getPublicUrl(objectKey));
|
||||
} finally {
|
||||
ossClient.shutdown();
|
||||
}
|
||||
@@ -113,32 +110,32 @@ public class OssStorageService {
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 objectKey 生成预签名下载 URL(1小时有效)。
|
||||
* 根据 objectKey 生成公开直链下载 URL。
|
||||
*/
|
||||
public String generateDownloadUrl(String objectKey) {
|
||||
OSS ossClient = buildClient();
|
||||
try {
|
||||
Date expiration = new Date(System.currentTimeMillis() + 3600_000L);
|
||||
URL url = ossClient.generatePresignedUrl(ossProperties.getBucket(), objectKey, expiration);
|
||||
return url.toString();
|
||||
} finally {
|
||||
ossClient.shutdown();
|
||||
}
|
||||
return getPublicUrl(objectKey);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取公开(无签名)URL,格式:https://{bucket}.{endpoint}/{objectKey}
|
||||
*/
|
||||
public String getPublicUrl(String objectKey) {
|
||||
if (objectKey == null || objectKey.isBlank()) {
|
||||
public String getPublicUrl(String value) {
|
||||
if (value == null || value.isBlank()) {
|
||||
return null;
|
||||
}
|
||||
return String.format("https://%s.%s/%s", ossProperties.getBucket(), ossProperties.getEndpoint(), objectKey);
|
||||
String objectKey = resolveObjectKey(value);
|
||||
String normalizedKey = objectKey.startsWith("/") ? objectKey.substring(1) : objectKey;
|
||||
String host = String.format("%s.%s", ossProperties.getBucket(), ossProperties.getEndpoint());
|
||||
try {
|
||||
return new URI("https", host, "/" + normalizedKey, null).toASCIIString();
|
||||
} catch (Exception ignored) {
|
||||
return String.format("https://%s/%s", host, normalizedKey);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从存储值中解析出 objectKey,兼容两种格式:
|
||||
* - 旧格式:完整预签名 URL(https://bucket.endpoint/objectKey?Expires=...)
|
||||
* - 旧格式:完整 URL(https://bucket.endpoint/objectKey?Expires=...)
|
||||
* - 新格式:直接是 objectKey(如 result/dedupe/uuid/file.xlsx)
|
||||
*/
|
||||
public String resolveObjectKey(String value) {
|
||||
@@ -151,13 +148,21 @@ public class OssStorageService {
|
||||
return path.startsWith("/") ? path.substring(1) : path;
|
||||
}
|
||||
} catch (Exception ignored) {
|
||||
int schemeEnd = value.indexOf("://");
|
||||
int pathStart = schemeEnd < 0 ? -1 : value.indexOf('/', schemeEnd + 3);
|
||||
if (pathStart >= 0 && pathStart + 1 < value.length()) {
|
||||
String path = value.substring(pathStart + 1);
|
||||
int queryStart = path.indexOf('?');
|
||||
String objectKey = queryStart >= 0 ? path.substring(0, queryStart) : path;
|
||||
return URLDecoder.decode(objectKey, StandardCharsets.UTF_8);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据存储值(objectKey 或旧格式预签名 URL)生成新鲜的预签名下载 URL。
|
||||
* 供各模块 listHistory 使用,每次按需生成,避免旧 URL 1小时后过期。
|
||||
* 根据存储值(objectKey 或旧格式完整 URL)生成公开直链下载 URL。
|
||||
* 供各模块 listHistory 和下载接口使用,避免签名过期。
|
||||
*/
|
||||
public String generateFreshDownloadUrl(String value) {
|
||||
if (value == null || value.isBlank()) {
|
||||
|
||||
Reference in New Issue
Block a user