为什么写这篇文章
项目里面使用到了七牛云,原来是基于七牛云的SDK来实现,后面由于内网部署的问题,考虑换成Minio,此时面临一个问题,需要修改代码。如果后期要换成阿里的SSO呢?或者换成腾讯云呢?那每次都要修改代码太麻烦,而且最主要的是我的需求可能是在内网环境我使用Minio,而在外网环境我又要使用七牛云。有没有一种办法是不需要修改代码只修改一些配置文件就能切换多个云平台呢?找了一下,AWS的S3应该是满足的。
我理解的AWS S3
S3是亚马逊平台的文件管理协议,猜测是因为用的人多且推出较早,后期推出的很多云存储都对S3协议有支持,比如七牛云的支持连接:https://developer.qiniu.com/kodo/4086/aws-s3-compatible
其他的阿里云,腾讯云,Minio据说也是支持的
如何使用(基于Springboot项目)
1、导入maven包
xml
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.12.540</version>
</dependency>
2、增加yml相关配置
yml
s3:
accessKey: xxx
secretKey: xxx
bucketName: xx
endpoint: https://s3.cn-south-1.qiniucs.com
region: cn-south-1
3、S3ClientConfig
java
package com.yrt.framework.config;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.client.builder.AwsClientBuilder;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author :GuangXiZhong
* @date :Created in 2025/6/10 15:21
* @description:
*/
@Configuration
public class S3ClientConfig {
@Value("${s3.accessKey}")
private String accessKey;
@Value("${s3.secretKey}")
private String secretKey;
@Value("${s3.endpoint}")
private String endpoint;
@Value("${s3.region}")
private String region;
@Bean
public AmazonS3 amazonS3Client() {
// 初始化 S3 客户端
AwsClientBuilder.EndpointConfiguration endpointConfiguration = new AwsClientBuilder.EndpointConfiguration(endpoint, region);
BasicAWSCredentials awsCreds = new BasicAWSCredentials(accessKey, secretKey);
return AmazonS3ClientBuilder.standard()
.withEndpointConfiguration(endpointConfiguration)
.withCredentials(new AWSStaticCredentialsProvider(awsCreds))
.build();
}
}
4、S3Service上传服务
java
package com.yrt.common.utils;
import com.amazonaws.HttpMethod;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.model.DeleteObjectRequest;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Date;
@Service
public class S3Service {
@Value("${s3.bucketName}")
private String bucketName;
@Autowired
private AmazonS3 s3Client;
// 上传文件
public String uploadFile(String key, File file) {
s3Client.putObject(new PutObjectRequest(bucketName, key, file));
return s3Client.getUrl(bucketName, key).toString();
}
// 上传文件并指定文件名
public String uploadFileWithKey(String key, InputStream inputStream) throws IOException {
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(inputStream.available());
s3Client.putObject(new PutObjectRequest(bucketName, key, inputStream, metadata));
return s3Client.getUrl(bucketName, key).toString();
}
// 删除文件
public void deleteFile(String key) {
s3Client.deleteObject(new DeleteObjectRequest(bucketName, key));
}
// 获取文件的公共访问链接
public String getFilePublicUrl(String key) {
return s3Client.getUrl(bucketName, key).toString();
}
// 获取文件的私有访问链接(带签名)
public String getFileSignedUrl(String key, long expirationTime) {
Date expirationDate = new Date(System.currentTimeMillis() + expirationTime);
GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(bucketName, key)
.withMethod(HttpMethod.GET)
.withExpiration(expirationDate);
URL signedUrl = s3Client.generatePresignedUrl(request);
return signedUrl.toString();
}
}
5、测试
java
package com.yrt;
import com.yrt.common.utils.S3Service;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import java.io.File;
/**
* @author :GuangXiZhong
* @date :Created in 2025/4/23 16:06
* @description:
*/
@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@ActiveProfiles("dev")
public class S3Test {
@Autowired
private S3Service s3Service;
/**
* S3测试
*/
@org.junit.Test
public void testS3() {
File file = new File("/Users/zhongguangxi/Documents/测试图片.png");
System.out.println(s3Service.uploadFile("test2561018", file));
}
}
运行一下可以看到输出了URL,说明成功了,此时去七牛空间看一下也能看到确实上传上去了
