JAVA 整合 亚马逊AWS S3(文件上传,文件下载)
1.添加依赖
因为aws需要发送请求上传、下载等api,所以需要加上httpclient相关的依赖
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>1.12.198</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3-transfer-manager</artifactId>
<version>2.20.26</version>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>kms</artifactId>
</dependency>
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3control</artifactId>
</dependency>
2.配置AWS S3相关的信息
package com.ezfos.common.s3.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "aws.s3")
public class AwzS3Config {
// 访问密钥
private String accessKey;
// 秘密密钥
private String secretKey;
// 存储桶名称
private String bucket;
// 区域
private String region;
// 前缀
private String prefix;
}
3.创建一个S3Client对象
S3Client是Amazon Web Services(AWS)的SDK中的一个类,用于与Amazon S3服务进行交互。该方法使用了@Bean
注解,表示它是一个Spring框架中的Bean定义,可以被其他组件注入使用。在方法内部,
首先通过AwsBasicCredentials.create()
方法创建了一个AwsBasicCredentials
对象,该对象包含了访问AWS所需的凭证信息,包括访问密钥和秘密密钥。
然后,使用S3Client.builder()
方法创建了一个S3Client
对象的构建器,并设置了以下配置:
region(Region.of(awzS3Config.getRegion()))
:设置AWS的区域信息,从awzS3Config
对象中获取区域值。credentialsProvider(StaticCredentialsProvider.create(awsCreds))
:设置凭证提供者,使用前面创建的AwsBasicCredentials
对象作为凭证。
最后,调用build()
方法构建并返回一个S3Client
对象。
请注意,代码中有一行被注释掉的代码:endpointOverride(URI.create("https://xxxxx(桶名).s3.cn-northwest-1.amazonaws.com"))
。这行代码用于指定自定义的S3端点URL,如果需要使用自定义的S3端点,可以取消注释并修改为正确的URL。
package com.ezfos.common.s3.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import javax.annotation.Resource;
@Component
@Configuration
public class S3Config {
@Resource
private AwzS3Config awzS3Config;
@Bean
public S3Client s3client() {
AwsBasicCredentials awsCreds = AwsBasicCredentials.create(awzS3Config.getAccessKey(), awzS3Config.getSecretKey());
S3Client s3Client = S3Client.builder().
region(Region.of(awzS3Config.getRegion())).
credentialsProvider(StaticCredentialsProvider.create(awsCreds)).build();
// endpointOverride(URI.create("https://xxxxx(桶名).s3.cn-northwest-1.amazonaws.com")).build();
return s3Client;
}
}
4.实现上传文件
/**
* 上传文件
*
* @param file
* @param uploadKey
* @return
*/
public boolean uploadToS3(MultipartFile file, String uploadKey) {
try {
if (file == null) {
return false;
}
//添加文件夹dev(文件夹其实就是一个前缀)
String prefix = awzS3Config.getPrefix();
String folderKey = prefix.concat(uploadKey);
PutObjectRequest putObjectRequest = PutObjectRequest.builder().bucket(awzS3Config.getBucket()).key(folderKey).contentType(file.getContentType()).build();
s3Client.putObject(putObjectRequest, RequestBody.fromBytes(file.getBytes()));
return true;
} catch (S3Exception | IOException e) {
e.printStackTrace();
return false;
}
}
5.实现下载文件
/**
* 下载文件
*
* @param response
* @param downloadKey
* @return
* @throws IOException
*/
public HttpServletResponse downloadFromS3(HttpServletResponse response, String downloadKey, String fileName) throws IOException {
// S3上存储的key
String keyName = awzS3Config.getPrefix().concat(downloadKey);
GetObjectRequest objectRequest = GetObjectRequest
.builder()
.key(keyName)
.bucket(awzS3Config.getBucket())
.build();
InputStream inputStream = null;
InputStream fis = null;
try {
ResponseBytes<GetObjectResponse> objectBytes = s3Client.getObjectAsBytes(objectRequest);
inputStream = objectBytes.asInputStream();
// 取得文件的后缀名。
// 以流的形式下载文件。
fis = new BufferedInputStream(inputStream);
byte[] buffer = new byte[fis.available()];
fis.read(buffer);
fis.close();
// 清空response
response.reset();
// 设置response的Header
response.setCharacterEncoding("UTF-8");
//Content-Disposition的作用:告知浏览器以何种方式显示响应返回的文件,用浏览器打开还是以附件的形式下载到本地保存
//attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.mp3"
// filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"