JAVA 整合 亚马逊AWS S3(文件上传,文件下载等)
package com.ezfos.common.s3.service;
import com.ezfos.common.s3.config.AwzS3Config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.core.ResponseBytes;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.model.*;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.time.Duration;
import java.util.ArrayList;
@Component
@Slf4j
public class S3service {
@Resource
private S3Client s3Client;
@Resource
private AwzS3Config awzS3Config;
/**
* 上传文件
*
* @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;
}
}
/**
* 上传文件
*
* @param uploadKey
* @return
*/
public boolean uploadToS3ByBytes(byte[] bytes, String contentType, String uploadKey) {
try {
//添加文件夹dev(文件夹其实就是一个前缀)
String prefix = awzS3Config.getPrefix();
String folderKey = prefix.concat(uploadKey);
PutObjectRequest putObjectRequest = PutObjectRequest.builder().bucket(awzS3Config.getBucket()).key(folderKey).contentType(contentType).build();
s3Client.putObject(putObjectRequest, RequestBody.fromBytes(bytes));
return true;
} catch (S3Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 获取文件输入流
* @param downloadKey
* @return inputStream
*/
public InputStream getInputStream(String downloadKey) {
InputStream inputStream = null;
try {
// S3上存储的key
String keyName = awzS3Config.getPrefix().concat(downloadKey);
GetObjectRequest objectRequest = GetObjectRequest
.builder()
.key(keyName)
.bucket(awzS3Config.getBucket())
.build();
ResponseBytes<GetObjectResponse> objectBytes = s3Client.getObjectAsBytes(objectRequest);
inputStream = objectBytes.asInputStream();
}catch (Exception e){
log.error("【S3报错】-" + e);
}
return inputStream;
}
/**
* 下载文件
*
* @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"));
// 告知浏览器文件的大小
response.addHeader("Content-Length", "" + buffer.length);
OutputStream outputStream = new BufferedOutputStream(response.getOutputStream());
response.setContentType("application/octet-stream");
outputStream.write(buffer);
outputStream.flush();
} catch (IOException ex) {
throw new IOException(ex);
} finally {
if (inputStream != null) {
inputStream.close();
}
}
return response;
}
/**
* 获取文件预览地址
*
* @param getKey
* @return
*/
public String getPresignedUrl(String getKey) {
if(getKey == null || "".equals(getKey)){
return null;
}
String theUrl;
String keyName = awzS3Config.getPrefix().concat(getKey);
AwsBasicCredentials awsCreds = AwsBasicCredentials.create(awzS3Config.getAccessKey(), awzS3Config.getSecretKey());
S3Presigner presigner = S3Presigner.builder()
.region(Region.of(awzS3Config.getRegion()))
.credentialsProvider(StaticCredentialsProvider.create(awsCreds))
.build();
try {
GetObjectRequest getObjectRequest = GetObjectRequest.builder()
.bucket(awzS3Config.getBucket())
.key(keyName)
.build();
GetObjectPresignRequest getObjectPresignRequest = GetObjectPresignRequest.builder()
.signatureDuration(Duration.ofDays(1))
.getObjectRequest(getObjectRequest)
.build();
PresignedGetObjectRequest presignedGetObjectRequest = presigner.presignGetObject(getObjectPresignRequest);
theUrl = presignedGetObjectRequest.url().toString();
} catch (S3Exception e) {
e.getStackTrace();
return null;
}
return theUrl;
}
/**
* 删除文件
*
* @param delKey
* @return
*/
public boolean deleteBucketObjects(String delKey) {
String keyName = awzS3Config.getPrefix().concat(delKey);
ArrayList<ObjectIdentifier> toDelete = new ArrayList<>();
toDelete.add(ObjectIdentifier.builder()
.key(keyName)
.build());
try {
DeleteObjectsRequest dor = DeleteObjectsRequest.builder()
.bucket(awzS3Config.getBucket())
.delete(Delete.builder().objects(toDelete).build())
.build();
s3Client.deleteObjects(dor);
} catch (S3Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public boolean existsFile(String getKey){
try {
// S3上存储的key
String keyName = awzS3Config.getPrefix().concat(getKey);
GetObjectRequest objectRequest = GetObjectRequest
.builder()
.key(keyName)
.bucket(awzS3Config.getBucket())
.build();
InputStream inputStream =s3Client.getObject(objectRequest);
if (inputStream == null){
return false;
}else {
return true;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
}