• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

weimin96 / oss-spring-boot-starter / #5

06 Apr 2026 02:14PM UTC coverage: 42.506% (-21.1%) from 63.625%
#5

push

github

web-flow
Merge pull request #9 from weimin96/spring3

Spring3

52 of 509 new or added lines in 8 files covered. (10.22%)

536 of 1261 relevant lines covered (42.51%)

0.43 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

34.88
/oss-spring-boot3-starter/src/main/java/com/wiblog/oss/service/PresignOperations.java
1
package com.wiblog.oss.service;
2

3
import com.wiblog.oss.bean.OssProperties;
4
import com.wiblog.oss.util.Util;
5
import lombok.extern.slf4j.Slf4j;
6
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
7
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
8
import software.amazon.awssdk.regions.Region;
9
import software.amazon.awssdk.services.s3.S3AsyncClient;
10
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
11
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
12
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
13
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
14
import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest;
15
import software.amazon.awssdk.transfer.s3.S3TransferManager;
16

17
import java.net.URI;
18
import java.net.URL;
19
import java.time.Duration;
20
import java.util.Map;
21

22
/**
23
 * 预签名 URL 操作。
24
 *
25
 * <p>预签名 URL 允许无需 AWS 凭证的客户端临时访问或上传对象。
26
 * 典型场景:前端直传(Pre-signed PUT)、CDN 临时下载链接(Pre-signed GET)。</p>
27
 *
28
 * @author panwm
29
 */
30
@Slf4j
1✔
31
public class PresignOperations extends Operations {
32

33
    /**
34
     * 默认预签名有效期(1 小时)。
35
     */
36
    private static final Duration DEFAULT_EXPIRATION = Duration.ofHours(1);
1✔
37

38
    private final S3Presigner presigner;
39

40
    public PresignOperations(OssProperties ossProperties, S3AsyncClient client,
41
                             S3TransferManager transferManager) {
42
        super(ossProperties, client, transferManager);
1✔
43
        this.presigner = buildPresigner(ossProperties);
1✔
44
    }
1✔
45

46
    // ----------------------------------------------------------------
47
    // Pre-signed GET(下载)
48
    // ----------------------------------------------------------------
49

50
    /**
51
     * 生成用于下载的预签名 URL,有效期为默认 1 小时。
52
     *
53
     * @param objectName 对象 key
54
     * @return 预签名 URL 字符串
55
     */
56
    public String generateGetPresignedUrl(String objectName) {
NEW
57
        return generateGetPresignedUrl(ossProperties.getBucketName(), objectName, DEFAULT_EXPIRATION);
×
58
    }
59

60
    /**
61
     * 生成用于下载的预签名 URL,自定义有效期。
62
     *
63
     * @param objectName 对象 key
64
     * @param expiration 有效时长(最大 7 天)
65
     * @return 预签名 URL 字符串
66
     */
67
    public String generateGetPresignedUrl(String objectName, Duration expiration) {
NEW
68
        return generateGetPresignedUrl(ossProperties.getBucketName(), objectName, expiration);
×
69
    }
70

71
    /**
72
     * 跨 Bucket 生成下载预签名 URL。
73
     */
74
    public String generateGetPresignedUrl(String bucketName, String objectName, Duration expiration) {
NEW
75
        GetObjectRequest getRequest = GetObjectRequest.builder()
×
NEW
76
                .bucket(bucketName)
×
NEW
77
                .key(Util.formatPath(objectName))
×
NEW
78
                .build();
×
79

NEW
80
        GetObjectPresignRequest presignRequest = GetObjectPresignRequest.builder()
×
NEW
81
                .signatureDuration(expiration)
×
NEW
82
                .getObjectRequest(getRequest)
×
NEW
83
                .build();
×
84

NEW
85
        URL url = presigner.presignGetObject(presignRequest).url();
×
NEW
86
        log.debug("Generated GET presigned URL for [{}], expires in {}", objectName, expiration);
×
NEW
87
        return url.toString();
×
88
    }
89

90
    // ----------------------------------------------------------------
91
    // Pre-signed PUT(前端直传)
92
    // ----------------------------------------------------------------
93

94
    /**
95
     * 生成用于上传的预签名 URL,有效期为默认 1 小时。
96
     *
97
     * <p>前端可直接用此 URL 发起 HTTP PUT 请求上传文件,无需经过后端服务器。</p>
98
     *
99
     * @param objectName  目标对象 key
100
     * @param contentType 文件 MIME 类型,例如 "image/jpeg"
101
     * @return 预签名 URL 字符串
102
     */
103
    public String generatePutPresignedUrl(String objectName, String contentType) {
NEW
104
        return generatePutPresignedUrl(ossProperties.getBucketName(), objectName,
×
105
                contentType, DEFAULT_EXPIRATION, null);
106
    }
107

108
    /**
109
     * 生成用于上传的预签名 URL,支持自定义元数据。
110
     *
111
     * @param objectName  目标对象 key
112
     * @param contentType MIME 类型
113
     * @param expiration  有效时长
114
     * @param metadata    自定义元数据(将作为 x-amz-meta-* 头部)
115
     * @return 预签名 URL 字符串
116
     */
117
    public String generatePutPresignedUrl(String objectName, String contentType,
118
                                          Duration expiration, Map<String, String> metadata) {
NEW
119
        return generatePutPresignedUrl(ossProperties.getBucketName(), objectName,
×
120
                contentType, expiration, metadata);
121
    }
122

123
    /**
124
     * 跨 Bucket 生成上传预签名 URL。
125
     */
126
    public String generatePutPresignedUrl(String bucketName, String objectName,
127
                                          String contentType, Duration expiration,
128
                                          Map<String, String> metadata) {
NEW
129
        PutObjectRequest.Builder putBuilder = PutObjectRequest.builder()
×
NEW
130
                .bucket(bucketName)
×
NEW
131
                .key(Util.formatPath(objectName))
×
NEW
132
                .contentType(contentType);
×
133

NEW
134
        if (metadata != null && !metadata.isEmpty()) {
×
NEW
135
            putBuilder.metadata(metadata);
×
136
        }
137

NEW
138
        PutObjectPresignRequest presignRequest = PutObjectPresignRequest.builder()
×
NEW
139
                .signatureDuration(expiration)
×
NEW
140
                .putObjectRequest(putBuilder.build())
×
NEW
141
                .build();
×
142

NEW
143
        URL url = presigner.presignPutObject(presignRequest).url();
×
NEW
144
        log.debug("Generated PUT presigned URL for [{}], expires in {}", objectName, expiration);
×
NEW
145
        return url.toString();
×
146
    }
147

148
    // ----------------------------------------------------------------
149
    // 资源释放
150
    // ----------------------------------------------------------------
151

152
    /**
153
     * 关闭预签名客户端(随 OssTemplate 生命周期管理)。
154
     */
155
    public void close() {
156
        if (presigner != null) {
1✔
157
            presigner.close();
1✔
158
        }
159
    }
1✔
160

161
    // ----------------------------------------------------------------
162
    // 私有工具
163
    // ----------------------------------------------------------------
164

165
    private static S3Presigner buildPresigner(OssProperties props) {
166
        StaticCredentialsProvider credentials = StaticCredentialsProvider.create(
1✔
167
                AwsBasicCredentials.create(props.getAccessKey(), props.getSecretKey()));
1✔
168

169
        S3Presigner.Builder builder = S3Presigner.builder()
1✔
170
                .credentialsProvider(credentials)
1✔
171
                .region(Region.US_EAST_1)
1✔
172
                .endpointOverride(URI.create(props.getEndpoint()));
1✔
173

174
        return builder.build();
1✔
175
    }
176
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc