diff --git a/par-api/src/main/resources/application.yml b/par-api/src/main/resources/application.yml index 0f3b356..5bf96ae 100644 --- a/par-api/src/main/resources/application.yml +++ b/par-api/src/main/resources/application.yml @@ -53,6 +53,7 @@ par: secret-key: ${QINIU_SK:} bucket: ${QINIU_BUCKET:par-configs} region: ${QINIU_REGION:z2} + domain: ${QINIU_DOMAIN:} mediabot: psk: ${PAR_MEDIABOT_PSK:} admin: diff --git a/par-core/src/main/java/com/par/core/storage/QiniuStorageService.java b/par-core/src/main/java/com/par/core/storage/QiniuStorageService.java index 65339f1..67407e6 100644 --- a/par-core/src/main/java/com/par/core/storage/QiniuStorageService.java +++ b/par-core/src/main/java/com/par/core/storage/QiniuStorageService.java @@ -11,8 +11,15 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.stereotype.Service; +import java.net.URI; +import java.net.http.HttpClient; +import java.net.http.HttpRequest; +import java.net.http.HttpResponse; +import java.time.Duration; + /** * 七牛云存储(主存储)。 + * 读文件通过公开 URL 直接 HTTP GET,不依赖 SDK 内部 API。 */ @Slf4j @Service @@ -23,21 +30,30 @@ public class QiniuStorageService implements StorageService { private final BucketManager bucketManager; private final Auth auth; private final String bucket; + private final String cdnDomain; + private final HttpClient httpClient; public QiniuStorageService( @Value("${par.storage.qiniu.access-key:}") String ak, @Value("${par.storage.qiniu.secret-key:}") String sk, @Value("${par.storage.qiniu.bucket:par-configs}") String bucket, - @Value("${par.storage.qiniu.region:z2}") String region) { + @Value("${par.storage.qiniu.region:z2}") String region, + @Value("${par.storage.qiniu.domain:}") String domain) { this.bucket = bucket; this.auth = Auth.create(ak, sk); + this.cdnDomain = domain != null && !domain.isBlank() + ? domain : "http://" + bucket + ".qiniucdn.com"; Configuration cfg = new Configuration(getRegion(region)); this.uploadManager = new UploadManager(cfg); this.bucketManager = new BucketManager(auth, cfg); + this.httpClient = HttpClient.newBuilder() + .connectTimeout(Duration.ofSeconds(5)) + .followRedirects(HttpClient.Redirect.NORMAL) + .build(); - log.info("Qiniu 存储就绪: bucket={}, region={}", bucket, region); + log.info("Qiniu 存储就绪: bucket={}, domain={}", bucket, cdnDomain); } @Override @@ -54,14 +70,18 @@ public class QiniuStorageService implements StorageService { @Override public String read(String path) { try { - // 构造公开下载 URL - String url = "http://" + bucket + ".qiniucdn.com/" + path; - var resp = bucketManager.get(url); - if (resp != null && resp.statusCode == 200) { - try { return resp.bodyString(); } catch (Exception e) { return new String(resp.body()); } + String url = cdnDomain + "/" + path; + var req = HttpRequest.newBuilder() + .uri(URI.create(url)) + .timeout(Duration.ofSeconds(10)) + .GET().build(); + var resp = httpClient.send(req, HttpResponse.BodyHandlers.ofString()); + if (resp.statusCode() == 200) { + return resp.body(); } - } catch (QiniuException e) { - log.warn("Qiniu 读取失败 {}: {}", path, e.response != null ? e.response.error : e.getMessage()); + log.warn("Qiniu 读取失败 {}: HTTP {}", path, resp.statusCode()); + } catch (Exception e) { + log.warn("Qiniu 读取失败 {}: {}", path, e.getMessage()); } return null; }