package com.iplatform.file.support;
|
|
import com.amazonaws.ClientConfiguration;
|
import com.amazonaws.Protocol;
|
import com.amazonaws.auth.AWSCredentials;
|
import com.amazonaws.auth.AWSStaticCredentialsProvider;
|
import com.amazonaws.auth.BasicAWSCredentials;
|
import com.amazonaws.auth.policy.Policy;
|
import com.amazonaws.auth.policy.Principal;
|
import com.amazonaws.auth.policy.Resource;
|
import com.amazonaws.auth.policy.Statement;
|
import com.amazonaws.auth.policy.actions.S3Actions;
|
import com.amazonaws.client.builder.AwsClientBuilder;
|
import com.amazonaws.regions.Regions;
|
import com.amazonaws.services.s3.AmazonS3;
|
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
|
import com.amazonaws.services.s3.model.BucketCrossOriginConfiguration;
|
import com.amazonaws.services.s3.model.CORSRule;
|
import com.amazonaws.services.s3.model.ObjectMetadata;
|
import com.amazonaws.services.s3.model.PutObjectRequest;
|
import com.amazonaws.services.s3.model.PutObjectResult;
|
import com.amazonaws.services.s3.model.S3Object;
|
import com.amazonaws.services.s3.model.S3ObjectInputStream;
|
import com.amazonaws.services.s3.model.SetBucketPolicyRequest;
|
import com.walker.file.DefaultFileInfo;
|
import com.walker.file.FileInfo;
|
import com.walker.file.FileOperateException;
|
import com.walker.file.FileStoreType;
|
import com.walker.infrastructure.utils.Base64;
|
import com.walker.infrastructure.utils.JsonUtils;
|
import com.walker.infrastructure.utils.StringUtils;
|
|
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayOutputStream;
|
import java.io.IOException;
|
import java.io.InputStream;
|
import java.util.Arrays;
|
import java.util.Calendar;
|
|
/**
|
* 亚马逊S3 OSS 实现。
|
*
|
* @author 时克英
|
* @date 2023-12-12
|
*/
|
public class AwsOssFileEngine extends AbstractOssFileEngine {
|
|
public AwsOssFileEngine() {
|
}
|
|
@Override
|
protected void executeUpload(InputStream inputStream, FileInfo fileInfo) throws FileOperateException {
|
//初始化对象元数据
|
ObjectMetadata metadata = new ObjectMetadata();
|
// metadata.setContentType("plain/text");
|
AmazonS3 client = this.acquireOneClient();
|
|
try {
|
String fileNameBase64 = new String(Base64.encode(fileInfo.getFileName().getBytes(StringUtils.DEFAULT_CHARSET_UTF8)));
|
metadata.addUserMetadata("x-amz-meta-title", fileNameBase64);
|
metadata.setContentLength(fileInfo.getFileSize());
|
//设置对象元数据
|
String objectKey = fileInfo.getId();
|
logger.debug("准备上传文件 objectKey = {}", objectKey);
|
// String objectKey = createFileOssPath(fileInfo.getId(), fileInfo.getFileExt());
|
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, objectKey, inputStream, metadata);
|
// PutObjectResult result = amazonS3Client.putObject(putObjectRequest);
|
PutObjectResult result = client.putObject(putObjectRequest);
|
|
System.out.println(JsonUtils.objectToJsonString(result));
|
StringBuilder url = new StringBuilder();
|
url.append(objectKey);
|
|
// ((DefaultFileInfo) fileInfo).setFileSize(result.getMetadata().getContentLength());
|
((DefaultFileInfo) fileInfo).setUrl(url.toString());
|
|
} catch (Exception var11) {
|
throw new FileOperateException("保存文件到【oss】错误:" + var11.getMessage() + ", id=" + fileInfo.getId(), var11);
|
} finally {
|
if(client != null){
|
client.shutdown();
|
}
|
}
|
}
|
|
@Override
|
protected byte[] executeDownload(FileInfo fileInfo) throws FileOperateException {
|
// throw new IllegalAccessError("不能调用OSS下载方法,请访问第三方链接");
|
|
AmazonS3 client = this.acquireOneClient();
|
S3ObjectInputStream objectContent = null;
|
ByteArrayOutputStream fileOutputStream = null;
|
try {
|
//下载对象
|
S3Object object = client.getObject(bucketName, fileInfo.getId());
|
//获取对象流
|
objectContent = object.getObjectContent();
|
//初始化文件输出流
|
// FileOutputStream fileOutputStream = new FileOutputStream(new File(file_path));
|
fileOutputStream = new ByteArrayOutputStream();
|
|
byte[] readbuf = new byte[1024 * 20];
|
int read_len = 0;
|
while ((read_len = objectContent.read(readbuf)) > 0) {
|
//对象下载字节写入文件输出流
|
fileOutputStream.write(readbuf, 0, read_len);
|
}
|
return fileOutputStream.toByteArray();
|
|
} catch (Exception ex) {
|
throw new FileOperateException("下载文件错误:" + ex.getMessage() + ", fileId=" + fileInfo.getId(), ex);
|
} finally {
|
//关闭流
|
try {
|
if(objectContent != null){
|
objectContent.close();
|
}
|
// if(fileOutputStream != null){
|
// fileOutputStream.close();
|
// }
|
if(client != null){
|
client.shutdown();
|
}
|
} catch (IOException e) {
|
// throw new RuntimeException(e);
|
logger.error("这里不需要抛出异常,仅用于调试知道流没有被关闭即可。", e);
|
}
|
}
|
}
|
|
@Override
|
public FileStoreType getFileStoreType() {
|
return FileStoreType.OssAws;
|
}
|
|
@Override
|
public void close() {
|
super.close();
|
this.closeAmazonS3Client();
|
}
|
|
private AmazonS3 acquireOneClient(){
|
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
ClientConfiguration clientConfiguration = new ClientConfiguration();
|
|
if (endpoint.contains("https")) {
|
clientConfiguration.setProtocol(Protocol.HTTPS);
|
logger.error("===================> HTTPS ");
|
} else {
|
clientConfiguration.setProtocol(Protocol.HTTP);
|
logger.error("===================> HTTP ");
|
}
|
return AmazonS3ClientBuilder.standard()
|
.withClientConfiguration(clientConfiguration)
|
.withEndpointConfiguration(
|
new AwsClientBuilder.EndpointConfiguration(this.endpoint, Regions.DEFAULT_REGION.getName()))
|
.withCredentials(new AWSStaticCredentialsProvider(credentials))
|
.build();
|
|
// AmazonS3 amazonS3Client = new AmazonS3Client(credentials, clientConfiguration);
|
// amazonS3Client.setEndpoint(endpoint);
|
// amazonS3Client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).disableChunkedEncoding().build());
|
// return amazonS3Client;
|
}
|
|
/**
|
* 初始化amazonS3Client
|
* @author 时克英
|
* @date 2024-02-02 使用多例,无需初始化,废弃方法。
|
*/
|
@Deprecated
|
public void initS3Client() {
|
logger.warn("不再使用单例,无需初始化,每次上传下载会创建新客户端连接!");
|
// AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey); //创建AWS凭证
|
// ClientConfiguration connconfig = new ClientConfiguration(); //初始化客户端config
|
// connconfig.setProtocol(Protocol.HTTP); //设置mos 请求协议为http
|
//
|
// //使用AWS凭证和clientConfiguration初始化AmazonS3Client客户端
|
// amazonS3Client = new AmazonS3Client(credentials, connconfig);
|
// amazonS3Client.setEndpoint(endpoint); ////设置mos对象服务接口地址
|
// amazonS3Client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).disableChunkedEncoding().build());
|
|
|
// AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
// ClientConfiguration clientConfiguration = new ClientConfiguration();
|
//
|
// if (endpoint.contains("https")) {
|
// clientConfiguration.setProtocol(Protocol.HTTPS);
|
// logger.error("===================> HTTPS ");
|
// } else {
|
// clientConfiguration.setProtocol(Protocol.HTTP);
|
// logger.error("===================> HTTP ");
|
// }
|
//
|
// AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endpoint, "beijing1");
|
// AWSCredentialsProvider credentialsProvider = new AWSStaticCredentialsProvider(credentials);
|
//
|
//
|
// amazonS3Client = AmazonS3ClientBuilder.standard()
|
// .withEndpointConfiguration(endpointConfiguration)
|
// .withCredentials(credentialsProvider).build();
|
//// amazonS3Client = new AmazonS3Client(credentials, clientConfiguration);
|
//// amazonS3Client.setEndpoint(endpoint);
|
//// amazonS3Client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).disableChunkedEncoding().build());
|
|
|
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
|
ClientConfiguration clientConfiguration = new ClientConfiguration();
|
|
if (endpoint.contains("https")) {
|
clientConfiguration.setProtocol(Protocol.HTTPS);
|
logger.error("===================> HTTPS ");
|
} else {
|
clientConfiguration.setProtocol(Protocol.HTTP);
|
logger.error("===================> HTTP ");
|
}
|
// 设置允许打开的最大 HTTP 连接数,默认为 50 个,此示例代码设置为 100 个。
|
// clientConfiguration.setMaxConnections(100 * 2);
|
// // 设置 Socket 层传输数据的超时时间(单位:毫秒),默认为 50000 毫秒,此示例代码设置为 60000 毫秒。
|
// clientConfiguration.setSocketTimeout(60000 * 2);
|
// // 设置建立连接的超时时间(单位:毫秒),默认为 10000 毫秒,此示例代码设置为 5000 毫秒。
|
// clientConfiguration.setConnectionTimeout(5000 * 2);
|
// // 设置等待请求完成的超时时间(单位:毫秒)。默认不超时(0),此示例代码设置为 60000 毫秒。
|
// clientConfiguration.setRequestTimeout(60000 * 2);
|
// // 设置客户端请求执行超时时间(单位:毫秒)。默认不超时(0),此示例代码设置为 60000 毫秒。
|
// clientConfiguration.setClientExecutionTimeout(60000 * 2);
|
// // 设置连接空闲超时时间。超时则关闭连接,默认为 60000 毫秒,此示例代码设置为 90000 毫秒。
|
//// clientConfiguration.setConnectionMaxIdleMillis(90000 * 2);
|
// // 设置请求失败后最大的重试次数,默认 3 次,此示例代码设置为 5 次。
|
// clientConfiguration.setMaxErrorRetry(5);
|
// 设置连接 EOS 所使用的协议(HTTP 或 HTTPS),默认为 HTTPS,此示例代码设置为 HTTP。
|
// clientConfiguration.setProtocol(Protocol.HTTP);
|
// 设置用户代理前缀,即 HTTP 的 User-Agent 头的前缀,此示例代码设置为 "EOS S3 Java SDK"。
|
// clientConfiguration.setUserAgentPrefix("EOS S3 Java SDK");
|
// 设置用户代理后缀,即 HTTP 的 User-Agent 头的后缀,此示例代码设置为 "1.12.378"。
|
// clientConfiguration.setUserAgentSuffix("1.12.378");
|
// 设置签名算法,默认为 v4 签名。此示例代码设置为 S3SignerType,即采用 v2 签名。
|
// clientConfiguration.setSignerOverride("S3SignerType");
|
|
// 2024-02-02,不用单例,使用多例即:每次调用创建客户端方式!
|
// amazonS3Client = new AmazonS3Client(credentials, clientConfiguration);
|
// amazonS3Client.setEndpoint(endpoint);
|
// amazonS3Client.setS3ClientOptions(S3ClientOptions.builder().setPathStyleAccess(true).disableChunkedEncoding().build());
|
}
|
|
/**
|
* 对应MOS JAVA SDK文档4.3.6章节 设置存储桶策略
|
*/
|
@Deprecated
|
public void setBucketPolicy() throws IOException {
|
// List<String> readLines = Files.readLines(new File("policy.txt"), Charset.forName("utf8"));
|
// StringBuilder sb = new StringBuilder();
|
// for(String str : readLines)
|
// {
|
// sb.append(str);
|
// }
|
// System.out.println(sb.toString());
|
//
|
// //policy 信息查看项目根目录 policy.txt文件
|
// String policy = sb.toString();
|
// amazonS3Client.setBucketPolicy(bucket_name, policy);
|
|
//通过Policy类构建桶策略
|
Policy bucket_policy = new Policy().withStatements(new Statement(
|
Statement.Effect.Allow)
|
.withPrincipals(Principal.AllUsers)
|
.withActions(S3Actions.GetObject)
|
.withResources(
|
new Resource("arn:aws:s3:::" + bucketName + "/*")));
|
|
SetBucketPolicyRequest setBucketPolicyRequest = new SetBucketPolicyRequest(bucketName, bucket_policy.toJson());
|
|
//设置桶策略
|
// amazonS3Client.setBucketPolicy(setBucketPolicyRequest);
|
}
|
|
@Deprecated
|
public void configBucketCors() {
|
// 配置跨域访问策略
|
BucketCrossOriginConfiguration conf = new BucketCrossOriginConfiguration()
|
.withRules(
|
new CORSRule()
|
.withId("1")// 配置规则 ID
|
.withAllowedHeaders(Arrays.asList("*")) // 跨域请求可以使用的 HTTP 请求头部,支持通配符 *
|
.withAllowedMethods(Arrays.asList(CORSRule.AllowedMethods.GET, CORSRule.AllowedMethods.PUT))// 跨域请求允许的 HTTP 操作,例如:GET,PUT,HEAD,POST,DELETE
|
// .withAllowedOrigins(Arrays.asList("http://www.example1.com"))// 允许的访问来源,支持通配符 *,格式为:协议://域名[:端口]
|
// .withMaxAgeSeconds(30)// 跨域请求得到结果的有效期
|
);
|
// SetBucketCrossOriginConfigurationRequest req = new SetBucketCrossOriginConfigurationRequest("bkt", conf);
|
// amazonS3Client.setBucketCrossOriginConfiguration(req);
|
|
// 删除跨域访问策略
|
// amazonS3Client.deleteBucketCrossOriginConfiguration("1");
|
}
|
|
/**
|
* 关闭amazonS3Client
|
*/
|
private void closeAmazonS3Client() {
|
// if (this.amazonS3Client != null) {
|
// amazonS3Client.shutdown(); //关闭客户端
|
// }
|
}
|
|
public byte[] testDownload(String fileId){
|
DefaultFileInfo fileInfo = new DefaultFileInfo();
|
fileInfo.setId(fileId);
|
try {
|
return this.executeDownload(fileInfo);
|
} catch (FileOperateException e) {
|
throw new RuntimeException("下载oss文件报错:" + e.getMessage() + ", fileId=" + fileId, e);
|
}
|
}
|
|
public void setAccessKey(String accessKey) {
|
this.accessKey = accessKey;
|
}
|
|
public void setSecretKey(String secretKey) {
|
this.secretKey = secretKey;
|
}
|
|
public void setEndpoint(String endpoint) {
|
this.endpoint = endpoint;
|
}
|
|
public void setBucketName(String bucketName) {
|
this.bucketName = bucketName;
|
}
|
|
public void setProtocol(Protocol protocol) {
|
this.protocol = protocol;
|
}
|
|
private String bucketName = "ctoms-file";
|
public String endpoint = "http://10.2.36.9:8080";
|
private String accessKey = "4XJOR8RXEWWRVV8N4HOC";
|
private String secretKey = "1Dp2ua3lcCocEQJMf1VtHBABPfpkUxF4gGE3xacW";
|
private Protocol protocol = Protocol.HTTP;
|
|
// private AmazonS3 amazonS3Client;
|
|
public String createFileOssPath(String fileId, String ext) {
|
Calendar ca = Calendar.getInstance();
|
String year = ca.get(Calendar.YEAR) + "";
|
String mon = ca.get(Calendar.MONTH) + 1 + "";
|
String day = ca.get(Calendar.DAY_OF_MONTH) + "";
|
String directory = year + "/" + mon + "/" + day + "/";
|
// mkdirFolder(directory);
|
return fileId + StringUtils.SYMBOL_DOT + ext;
|
}
|
|
// 上传前上设置文件夹
|
public boolean mkdirFolder(String directory) {
|
AmazonS3 client = this.acquireOneClient();
|
PutObjectResult putObjectResult = client.putObject(bucketName, directory, new ByteArrayInputStream(new byte[0]), null);
|
return putObjectResult != null;
|
}
|
}
|