Commit ad00fbc566aed49a8ff23c1a5c2f516ce5c12ca1

Authored by segerts
1 parent d97ba8d4

S3 minio sdk 替换为 aws sdk

yudao-module-infra/yudao-module-infra-biz/pom.xml
@@ -116,8 +116,8 @@ @@ -116,8 +116,8 @@
116 <artifactId>jsch</artifactId> <!-- 文件客户端:解决 sftp 连接 --> 116 <artifactId>jsch</artifactId> <!-- 文件客户端:解决 sftp 连接 -->
117 </dependency> 117 </dependency>
118 <dependency> 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 </dependency> 121 </dependency>
122 122
123 <dependency> 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,10 +4,17 @@ import cn.hutool.core.io.IoUtil;
4 import cn.hutool.core.util.StrUtil; 4 import cn.hutool.core.util.StrUtil;
5 import cn.hutool.http.HttpUtil; 5 import cn.hutool.http.HttpUtil;
6 import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient; 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 import java.io.ByteArrayInputStream; 16 import java.io.ByteArrayInputStream;
  17 +import java.util.Date;
11 import java.util.concurrent.TimeUnit; 18 import java.util.concurrent.TimeUnit;
12 19
13 /** 20 /**
@@ -19,7 +26,7 @@ import java.util.concurrent.TimeUnit; @@ -19,7 +26,7 @@ import java.util.concurrent.TimeUnit;
19 */ 26 */
20 public class S3FileClient extends AbstractFileClient<S3FileClientConfig> { 27 public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
21 28
22 - private MinioClient client; 29 + private AmazonS3Client client;
23 30
24 public S3FileClient(Long id, S3FileClientConfig config) { 31 public S3FileClient(Long id, S3FileClientConfig config) {
25 super(id, config); 32 super(id, config);
@@ -32,26 +39,57 @@ public class S3FileClient extends AbstractFileClient&lt;S3FileClientConfig&gt; { @@ -32,26 +39,57 @@ public class S3FileClient extends AbstractFileClient&lt;S3FileClientConfig&gt; {
32 config.setDomain(buildDomain()); 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 .build(); 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 * 基于 bucket + endpoint 构建访问的 Domain 地址 95 * 基于 bucket + endpoint 构建访问的 Domain 地址
@@ -88,55 +126,69 @@ public class S3FileClient extends AbstractFileClient&lt;S3FileClientConfig&gt; { @@ -88,55 +126,69 @@ public class S3FileClient extends AbstractFileClient&lt;S3FileClientConfig&gt; {
88 } 126 }
89 127
90 /** 128 /**
91 - * 开启 VirtualStyle 模式 129 + * 开启 PathStyle模式
92 */ 130 */
93 private void enableVirtualStyleEndpoint() { 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 @Override 142 @Override
102 public String upload(byte[] content, String path, String type) throws Exception { 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 return config.getDomain() + "/" + path; 156 return config.getDomain() + "/" + path;
112 } 157 }
113 158
114 @Override 159 @Override
115 public void delete(String path) throws Exception { 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 @Override 170 @Override
123 public byte[] getContent(String path) throws Exception { 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 @Override 180 @Override
132 public FilePresignedUrlRespDTO getPresignedObjectUrl(String path) throws Exception { 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 return new FilePresignedUrlRespDTO(uploadUrl, config.getDomain() + "/" + path); 192 return new FilePresignedUrlRespDTO(uploadUrl, config.getDomain() + "/" + path);
141 } 193 }
142 194