Commit ad00fbc566aed49a8ff23c1a5c2f516ce5c12ca1
1 parent
d97ba8d4
S3 minio sdk 替换为 aws sdk
Showing
2 changed files
with
99 additions
and
47 deletions
yudao-module-infra/yudao-module-infra-biz/pom.xml
| ... | ... | @@ -116,8 +116,8 @@ |
| 116 | 116 | <artifactId>jsch</artifactId> <!-- 文件客户端:解决 sftp 连接 --> |
| 117 | 117 | </dependency> |
| 118 | 118 | <dependency> |
| 119 | - <groupId>io.minio</groupId> | |
| 120 | - <artifactId>minio</artifactId> <!-- 文件客户端:解决阿里云、腾讯云、minio 等 S3 连接 --> | |
| 119 | + <groupId>com.amazonaws</groupId> | |
| 120 | + <artifactId>aws-java-sdk-s3</artifactId><!-- 文件客户端:解决阿里云、腾讯云、minio 等 S3 连接 --> | |
| 121 | 121 | </dependency> |
| 122 | 122 | |
| 123 | 123 | <dependency> | ... | ... |
yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClient.java
| ... | ... | @@ -4,10 +4,17 @@ import cn.hutool.core.io.IoUtil; |
| 4 | 4 | import cn.hutool.core.util.StrUtil; |
| 5 | 5 | import cn.hutool.http.HttpUtil; |
| 6 | 6 | import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient; |
| 7 | -import io.minio.*; | |
| 8 | -import io.minio.http.Method; | |
| 7 | +import com.amazonaws.HttpMethod; | |
| 8 | +import com.amazonaws.auth.AWSStaticCredentialsProvider; | |
| 9 | +import com.amazonaws.auth.BasicAWSCredentials; | |
| 10 | +import com.amazonaws.client.builder.AwsClientBuilder; | |
| 11 | +import com.amazonaws.services.s3.*; | |
| 12 | +import com.amazonaws.services.s3.model.ObjectMetadata; | |
| 13 | +import com.amazonaws.services.s3.model.S3Object; | |
| 14 | + | |
| 9 | 15 | |
| 10 | 16 | import java.io.ByteArrayInputStream; |
| 17 | +import java.util.Date; | |
| 11 | 18 | import java.util.concurrent.TimeUnit; |
| 12 | 19 | |
| 13 | 20 | /** |
| ... | ... | @@ -19,7 +26,7 @@ import java.util.concurrent.TimeUnit; |
| 19 | 26 | */ |
| 20 | 27 | public class S3FileClient extends AbstractFileClient<S3FileClientConfig> { |
| 21 | 28 | |
| 22 | - private MinioClient client; | |
| 29 | + private AmazonS3Client client; | |
| 23 | 30 | |
| 24 | 31 | public S3FileClient(Long id, S3FileClientConfig config) { |
| 25 | 32 | super(id, config); |
| ... | ... | @@ -32,26 +39,57 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> { |
| 32 | 39 | config.setDomain(buildDomain()); |
| 33 | 40 | } |
| 34 | 41 | // 初始化客户端 |
| 35 | - client = MinioClient.builder() | |
| 36 | - .endpoint(buildEndpointURL()) // Endpoint URL | |
| 37 | - .region(buildRegion()) // Region | |
| 38 | - .credentials(config.getAccessKey(), config.getAccessSecret()) // 认证密钥 | |
| 42 | + | |
| 43 | + client = (AmazonS3Client)AmazonS3ClientBuilder.standard() | |
| 44 | + .withCredentials(buildCredentials()) | |
| 45 | + .withEndpointConfiguration(buildEndpointConfiguration()) | |
| 39 | 46 | .build(); |
| 40 | - enableVirtualStyleEndpoint(); | |
| 41 | - } | |
| 42 | 47 | |
| 48 | +// enableVirtualStyleEndpoint(); | |
| 49 | + | |
| 50 | +// client = AmazonS3ClientBuilder.builder() | |
| 51 | +// .endpoint(buildEndpointURL()) // Endpoint URL | |
| 52 | +// .region(buildRegion()) // Region | |
| 53 | +// .credentials(config.getAccessKey(), config.getAccessSecret()) // 认证密钥 | |
| 54 | +// .build(); | |
| 55 | +// enableVirtualStyleEndpoint(); | |
| 56 | + } | |
| 43 | 57 | /** |
| 44 | - * 基于 endpoint 构建调用云服务的 URL 地址 | |
| 58 | + * 基于config秘钥 构建 S3 客户端的认证信息 | |
| 45 | 59 | * |
| 46 | - * @return URI 地址 | |
| 60 | + * @return S3 客户端的认证信息 | |
| 47 | 61 | */ |
| 48 | - private String buildEndpointURL() { | |
| 49 | - // 如果已经是 http 或者 https,则不进行拼接.主要适配 MinIO | |
| 50 | - if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) { | |
| 51 | - return config.getEndpoint(); | |
| 52 | - } | |
| 53 | - return StrUtil.format("https://{}", config.getEndpoint()); | |
| 62 | + private AWSStaticCredentialsProvider buildCredentials() { | |
| 63 | + AWSStaticCredentialsProvider awsStaticCredentialsProvider = new AWSStaticCredentialsProvider( | |
| 64 | + new BasicAWSCredentials(config.getAccessKey(), config.getAccessSecret())); | |
| 65 | + return awsStaticCredentialsProvider; | |
| 54 | 66 | } |
| 67 | + /** | |
| 68 | + * 构建 S3 客户端的 Endpoint 配置包括 region、endpoint | |
| 69 | + * | |
| 70 | + * @return S3 客户端的 EndpointConfiguration 配置 | |
| 71 | + */ | |
| 72 | + private AwsClientBuilder.EndpointConfiguration buildEndpointConfiguration() { | |
| 73 | + AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration( | |
| 74 | + config.getEndpoint(), buildRegion()); | |
| 75 | + return endpointConfiguration; | |
| 76 | + } | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | +// /** | |
| 82 | +// * 基于 endpoint 构建调用云服务的 URL 地址 | |
| 83 | +// * | |
| 84 | +// * @return URI 地址 | |
| 85 | +// */ | |
| 86 | +// private String buildEndpointURL() { | |
| 87 | +// // 如果已经是 http 或者 https,则不进行拼接.主要适配 MinIO | |
| 88 | +// if (HttpUtil.isHttp(config.getEndpoint()) || HttpUtil.isHttps(config.getEndpoint())) { | |
| 89 | +// return config.getEndpoint(); | |
| 90 | +// } | |
| 91 | +// return StrUtil.format("https://{}", config.getEndpoint()); | |
| 92 | +// } | |
| 55 | 93 | |
| 56 | 94 | /** |
| 57 | 95 | * 基于 bucket + endpoint 构建访问的 Domain 地址 |
| ... | ... | @@ -88,55 +126,69 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> { |
| 88 | 126 | } |
| 89 | 127 | |
| 90 | 128 | /** |
| 91 | - * 开启 VirtualStyle 模式 | |
| 129 | + * 开启 PathStyle模式 | |
| 92 | 130 | */ |
| 93 | 131 | private void enableVirtualStyleEndpoint() { |
| 94 | - if (StrUtil.containsAny(config.getEndpoint(), | |
| 95 | - S3FileClientConfig.ENDPOINT_TENCENT, // 腾讯云 https://cloud.tencent.com/document/product/436/41284 | |
| 96 | - S3FileClientConfig.ENDPOINT_VOLCES)) { // 火山云 https://www.volcengine.com/docs/6349/1288493 | |
| 97 | - client.enableVirtualStyleEndpoint(); | |
| 98 | - } | |
| 132 | +// if (StrUtil.containsAny(config.getEndpoint(), | |
| 133 | +// S3FileClientConfig.ENDPOINT_TENCENT, // 腾讯云 https://cloud.tencent.com/document/product/436/41284 | |
| 134 | +// S3FileClientConfig.ENDPOINT_VOLCES)) { // 火山云 https://www.volcengine.com/docs/6349/1288493 | |
| 135 | +// | |
| 136 | +// } | |
| 137 | + S3ClientOptions clientOptions = S3ClientOptions.builder() | |
| 138 | + .setPathStyleAccess(true) | |
| 139 | + .build(); | |
| 99 | 140 | } |
| 100 | 141 | |
| 101 | 142 | @Override |
| 102 | 143 | public String upload(byte[] content, String path, String type) throws Exception { |
| 103 | 144 | // 执行上传 |
| 104 | - client.putObject(PutObjectArgs.builder() | |
| 105 | - .bucket(config.getBucket()) // bucket 必须传递 | |
| 106 | - .contentType(type) | |
| 107 | - .object(path) // 相对路径作为 key | |
| 108 | - .stream(new ByteArrayInputStream(content), content.length, -1) // 文件内容 | |
| 109 | - .build()); | |
| 145 | + ObjectMetadata objectMetadata = new ObjectMetadata(); | |
| 146 | + objectMetadata.setContentType(type); | |
| 147 | + | |
| 148 | + client.putObject(config.getBucket(), path, new ByteArrayInputStream(content), objectMetadata); | |
| 149 | +// client.putObject(PutObjectArgs.builder() | |
| 150 | +// .bucket(config.getBucket()) // bucket 必须传递 | |
| 151 | +// .contentType(type) | |
| 152 | +// .object(path) // 相对路径作为 key | |
| 153 | +// .stream(new ByteArrayInputStream(content), content.length, -1) // 文件内容 | |
| 154 | +// .build()); | |
| 110 | 155 | // 拼接返回路径 |
| 111 | 156 | return config.getDomain() + "/" + path; |
| 112 | 157 | } |
| 113 | 158 | |
| 114 | 159 | @Override |
| 115 | 160 | public void delete(String path) throws Exception { |
| 116 | - client.removeObject(RemoveObjectArgs.builder() | |
| 117 | - .bucket(config.getBucket()) // bucket 必须传递 | |
| 118 | - .object(path) // 相对路径作为 key | |
| 119 | - .build()); | |
| 161 | + | |
| 162 | + client.deleteObject(config.getBucket(), path); | |
| 163 | + | |
| 164 | +// client.removeObject(RemoveObjectArgs.builder() | |
| 165 | +// .bucket(config.getBucket()) // bucket 必须传递 | |
| 166 | +// .object(path) // 相对路径作为 key | |
| 167 | +// .build()); | |
| 120 | 168 | } |
| 121 | 169 | |
| 122 | 170 | @Override |
| 123 | 171 | public byte[] getContent(String path) throws Exception { |
| 124 | - GetObjectResponse response = client.getObject(GetObjectArgs.builder() | |
| 125 | - .bucket(config.getBucket()) // bucket 必须传递 | |
| 126 | - .object(path) // 相对路径作为 key | |
| 127 | - .build()); | |
| 128 | - return IoUtil.readBytes(response); | |
| 172 | + S3Object tempS3Object = client.getObject(config.getBucket(), path); | |
| 173 | +// GetObjectResponse response = client.getObject(GetObjectArgs.builder() | |
| 174 | +// .bucket(config.getBucket()) // bucket 必须传递 | |
| 175 | +// .object(path) // 相对路径作为 key | |
| 176 | +// .build()); | |
| 177 | + return IoUtil.readBytes(tempS3Object.getObjectContent()); | |
| 129 | 178 | } |
| 130 | 179 | |
| 131 | 180 | @Override |
| 132 | 181 | public FilePresignedUrlRespDTO getPresignedObjectUrl(String path) throws Exception { |
| 133 | - String uploadUrl = client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder() | |
| 134 | - .method(Method.PUT) | |
| 135 | - .bucket(config.getBucket()) | |
| 136 | - .object(path) | |
| 137 | - .expiry(10, TimeUnit.MINUTES) // 过期时间(秒数)取值范围:1 秒 ~ 7 天 | |
| 138 | - .build() | |
| 139 | - ); | |
| 182 | + //设定过期时间为24小时 | |
| 183 | + Date expiration = new Date(System.currentTimeMillis() + TimeUnit.HOURS.toMillis(24)); | |
| 184 | + String uploadUrl = String.valueOf(client.generatePresignedUrl(config.getBucket(), path,expiration , HttpMethod.PUT)); | |
| 185 | +// String uploadUrl = client.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder() | |
| 186 | +// .method(Method.PUT) | |
| 187 | +// .bucket(config.getBucket()) | |
| 188 | +// .object(path) | |
| 189 | +// .expiry(10, TimeUnit.MINUTES) // 过期时间(秒数)取值范围:1 秒 ~ 7 天 | |
| 190 | +// .build() | |
| 191 | +// ); | |
| 140 | 192 | return new FilePresignedUrlRespDTO(uploadUrl, config.getDomain() + "/" + path); |
| 141 | 193 | } |
| 142 | 194 | ... | ... |