1. 引入S3依赖
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
</dependency>
2. 配置准备
accessKey:公钥
secretKey:密钥
region:地区
buketName:桶
3. 初始化配置
@Bean
public AmazonS3 getAmazonS3() {
AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
AmazonS3 amazonS3 = AmazonS3ClientBuilder.standard()
.withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.withPathStyleAccessEnabled(true)
.withClientConfiguration(new ClientConfiguration())
.build();
return amazonS3;
}
4. 文件上传
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(multipartFile.getContentType());
objectMetadata.setContentLength(multipartFile.getSize());
String simpleUUID = IdUtil.simpleUUID();
PutObjectResult putObjectResult = amazonS3.putObject(new PutObjectRequest(bucketName, simpleUUID, multipartFile.getInputStream(), objectMetadata));
//PutObjectResult putObjectResult = amazonS3.putObject(new PutObjectRequest(bucketName, simpleUUID, multipartFile.getInputStream(), objectMetadata).withCannedAcl(CannedAccessControlList.PublicRead));
return "https://" + bucketName + ".s3-" + amazonS3.getRegionName() + ".amazonaws.com/" + URLEncoder.encode(simpleUUID);
5. 文件下载
方法一:
public static final byte[] download(String bucketName, String fileName) {
ClientConfiguration baseOpts = new ClientConfiguration();
baseOpts.setSignerOverride("S3SignerType");
AWSCredentials credentials = new BasicAWSCredentials(ACCESSKEY, SECRETKEY);
AmazonS3 client = new AmazonS3Client(credentials, baseOpts);
client.setEndpoint(HOSTNAME);
S3ClientOptions s3Opts = new S3ClientOptions();
s3Opts.setPathStyleAccess(true);
client.setS3ClientOptions(s3Opts);
S3Object downloadObject = client.getObject(new GetObjectRequest(bucketName, fileName));
S3ObjectInputStream downloadObjectInput = downloadObject.getObjectContent();
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
try {
while ((length = downloadObjectInput.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
return result.toByteArray();
} catch (IOException e1) {
log.error("S3 File download error,error:{}", e1);
} finally {
try {
downloadObjectInput.close();
result.close();
} catch (IOException e2) {
log.error("S3 File download error,error:{}", e2);
}
}
return null;
}
方法二:
public void amazonS3Downloading(String key,String targetFilePath) {
S3Object object = s3.getAmazonS3().getObject(new GetObjectRequest(bucketName, key));
if (object != null) {
log.info("Content-Type: " + object.getObjectMetadata().getContentType());
InputStream input = null;
FileOutputStream fileOutputStream = null;
byte[] data = null;
try {
//获取文件流
input = object.getObjectContent();
data = new byte[input.available()];
int len = 0;
fileOutputStream = new FileOutputStream(targetFilePath);
while ((len = input.read(data)) != -1) {
fileOutputStream.write(data, 0, len);
}
log.info("Downloading the file succeeded");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
以下是实际使用案例
pom.xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-s3</artifactId>
<version>1.11.415</version>
</dependency>
application.yml
aws:
accessKey: 公钥
secretKey: 私钥
region: 地区
hostName: endPoint信息
baseBucketName: 桶名
isLoadHostName: true
AwsConfig.java
/**
* @author ght
* @create 2021/12/08 13:26
*/
@Component
@ConfigurationProperties(prefix = "aws")
@Slf4j
public class AwsConfig {
@Value("${aws.accessKey}")
private String accessKey;
@Value("${aws.secretKey}")
private String secretKey;
@Value("${aws.region}")
private String region;
@Value("${aws.hostName}")
private String hostName;
@Value("${aws.baseBucketName}")
private String baseBucketName;
@Value("${aws.isLoadHostName}")
private Boolean isLoadHostName;
@Bean
public AmazonS3 getAmazonS3() {
AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
ClientConfiguration baseOpts = new ClientConfiguration();
/*if(isLoadHostName == null || isLoadHostName) {
baseOpts.setSignerOverride("S3SignerType");
baseOpts.setProtocol(Protocol.HTTPS);
}*/
AmazonS3 amazonS3 = AmazonS3ClientBuilder.standard()
// .withRegion(region)
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.withEndpointConfiguration(new AwsClientBuilder.EndpointConfiguration(hostName, region)) // 如果有endpoint,可以用这个,这个和withRegion(Region)不能一起使用
.withPathStyleAccessEnabled(true) // 如果配置了S3域名,就需要加这个进行路径访问,要不然会报AccessKey不存在的问题
.withClientConfiguration(baseOpts)
.build();
// amazonS3.setEndpoint(hostName);
/*if(isLoadHostName == null || isLoadHostName){
amazonS3.setEndpoint(hostName);
}*/
return amazonS3;
/*ClientConfiguration baseOpts = new ClientConfiguration();
baseOpts.setSignerOverride("S3SignerType");
AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);
AmazonS3 client = new AmazonS3Client(credentials, baseOpts);
client.setEndpoint(hostName);
S3ClientOptions s3Opts = new S3ClientOptions();
s3Opts.setPathStyleAccess(true);
client.setS3ClientOptions(s3Opts);
return client;*/
}
// @Bean
// public AmazonSimpleEmailService getAmazonSimpleEmailService() {
// AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
//
// AmazonSimpleEmailService amazonSimpleEmailService = AmazonSimpleEmailServiceClientBuilder.standard()
// .withRegion("eu-central-1")
// .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
// .withClientConfiguration(new ClientConfiguration())
// .build();
// return amazonSimpleEmailService;
// }
//
//
// @Bean
// public AmazonSNS getAmazonSNS(){
// AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
// AmazonSNS amazonSNS = AmazonSNSClientBuilder.standard()
// .withRegion("eu-central-1")
// .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
// .withClientConfiguration(new ClientConfiguration())
// .build();
// return amazonSNS;
// }
}
AwsService.java
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.List;
public interface AwsService {
/**
* 上传文件
*
* @param file 文件对象
* @param uploadPath 目标路径
* @return
*/
String uploadFile(File file, String uploadPath);
/**
* 上传文件
*
* @param multipartFile
* @return
*/
String uploadMultipartFile(MultipartFile multipartFile, String uploadPath);
/**
* 下载文件
*
* @param url
* @return
*/
String downloadFile(String url);
/**
* key:上传的文件,如:/aa/123.png 表示将123.png放到aa目录下的
* targetFilePath:下载的目标地址,如果是Linux建议用/tmp
*
* @param key
* @param targetFilePath
*/
void amazonS3Downloading(String key,String targetFilePath);
/**
* 创建桶
*
* @param bucketName
* @return
*/
String createBucket(String bucketName);
/**
* 删除桶
*
* @param bucketName
*/
void removeBucket(String bucketName);
/**
* 获取桶列表
*
* @return
*/
List listbuckets();
/**
* 获取某个桶中存储文件的列表
*
* @param bucket_name
* @return
*/
List listObject(String bucket_name);
/**
* 删除桶中的文件
*
* @param bucket_name
* @param objectName
*/
void deleteObject(String bucket_name,String objectName);
}
AwsServiceImpl.java
import com.amazonaws.services.s3.model.*;
import com.ecio.common.config.AwsConfig;
import com.ecio.common.utils.StringUtils;
import com.ecio.system.service.AwsService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@Slf4j
@Service
public class AwsServiceImpl implements AwsService {
@Value("${aws.accessKey}")
private String accessKey;
@Value("${aws.secretKey}")
private String secretKey;
@Value("${aws.region}")
private String region;
@Value("${aws.hostName}")
private String hostName;
@Value("${aws.baseBucketName}")
private String bucketName;
@Value("${aws.isLoadHostName}")
private Boolean isLoadHostName;
@Autowired
private AwsConfig s3;
@Override
public String uploadFile(File file, String uploadPath) {
try {
if (file == null) {
return null;
}
// 设置文件目录
if (StringUtils.isNotEmpty(uploadPath)) {
uploadPath = "/".equals(uploadPath.substring(uploadPath.length() - 1)) ? uploadPath : uploadPath + "/";
} else {
uploadPath = "default/";
}
// 生成随机文件名
String expandedName = file.getName().substring(file.getName().lastIndexOf("."));
String fileName = uploadPath + UUID.randomUUID().toString() + expandedName;
// 设置文件上传对象
PutObjectRequest request = new PutObjectRequest(bucketName, fileName, file);
// 设置公共读取
request.withCannedAcl(CannedAccessControlList.PublicRead);
// 上传文件
PutObjectResult putObjectResult = s3.getAmazonS3().putObject(request);
String result = hostName + File.separator + bucketName + File.separator + fileName;
log.info("上传文件到桶成功,地址信息:{}", result);
if (null != putObjectResult) {
return result;
}
} catch (Exception e) {
log.error("上传文件到桶失败:{}", e.getMessage());
e.printStackTrace();
}
return null;
}
@Override
public String uploadMultipartFile(MultipartFile multipartFile, String uploadPath) {
try {
ObjectMetadata objectMetadata = new ObjectMetadata();
objectMetadata.setContentType(multipartFile.getContentType());
objectMetadata.setContentLength(multipartFile.getSize());
String suffix = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));
log.info("suffix:{}",suffix);
String simpleUUID = UUID.randomUUID().toString();
log.info("simpleUUID:{}",simpleUUID);
String fileName = simpleUUID + suffix;
// 这里每一个分隔符表示一个图片
String key = uploadPath + File.separator + File.separator + fileName;
log.info("fileName:{}",fileName);
log.info("S3:{}",s3);
log.info("bucketName:{}",bucketName);
log.info("hostName:{}",hostName);
PutObjectResult putObjectResult = s3.getAmazonS3().putObject(new PutObjectRequest(bucketName, key, multipartFile.getInputStream(), objectMetadata));
String result = hostName + File.separator + bucketName + File.separator + uploadPath + File.separator + fileName;
log.info("Upload files to the bucket,address info:{}", result);
if (null != putObjectResult) {
return result;
}
} catch (Exception e) {
log.error("Upload files to the bucket,Failed:{}", e.getMessage());
e.printStackTrace();
}
return null;
}
@Override
public String downloadFile(String url) {
try {
if (StringUtils.isEmpty(url)) {
return null;
}
GeneratePresignedUrlRequest httpRequest = new GeneratePresignedUrlRequest(bucketName, url);
//设置过期时间
httpRequest.setExpiration(expirationDate);
return s3.getAmazonS3().generatePresignedUrl(httpRequest).toString();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public void amazonS3Downloading(String key,String targetFilePath) {
S3Object object = s3.getAmazonS3().getObject(new GetObjectRequest(bucketName, key));
if (object != null) {
log.info("Content-Type: " + object.getObjectMetadata().getContentType());
InputStream input = null;
FileOutputStream fileOutputStream = null;
byte[] data = null;
try {
//获取文件流
input = object.getObjectContent();
data = new byte[input.available()];
int len = 0;
fileOutputStream = new FileOutputStream(targetFilePath);
while ((len = input.read(data)) != -1) {
fileOutputStream.write(data, 0, len);
}
log.info("Downloading the file succeeded");
} catch (IOException e) {
e.printStackTrace();
} finally {
if (fileOutputStream != null) {
try {
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
@Override
public String createBucket(String bucketName) {
Bucket resp = s3.getAmazonS3().createBucket(bucketName);
String bucket = resp.getName();
return bucket;
}
@Override
public void removeBucket(String bucketName) {
s3.getAmazonS3().deleteBucket(bucketName);
}
@Override
public List listbuckets() {
List<String> buckets = new ArrayList<String>();
List<Bucket> resp = s3.getAmazonS3().listBuckets();
for (int i = 0; i < resp.size(); i++) {
String bucket = resp.get(i).getName();
buckets.add(bucket);
}
return buckets;
}
@Override
public List listObject(String bucket_name) {
List <String> objects = new ArrayList<String>();
ObjectListing resp = s3.getAmazonS3().listObjects(bucket_name);
List object_summary = resp.getObjectSummaries();
for (int i = 0;i<object_summary.size();i++) {
String object_name = object_summary.get(i).toString();
objects.add(object_name);
}
return objects;
}
@Override
public void deleteObject(String bucket_name, String objectName) {
s3.getAmazonS3().deleteObject(bucket_name, objectName);
}
}
public class UploadToS3Util {
// 创建s3对象
private static final S3Client s3Client = S3Client
.builder()
.region(Region.CN_NORTH_1) //桶所在的位置
.credentialsProvider(StaticCredentialsProvider.create(AwsSessionCredentials.create(AwsConfig.ACCESS_KEY, AwsConfig.SECRET_KEY,"")))
.build();
/**
* s3上传文件
* @param uploadKey bucket中的存储文件名
* @param file 待上传的文件流
*/
public static boolean uploadToS3(String uploadKey, byte[] file) {
try {
if (file == null) {
return false;
}
//添加文件夹dev(文件夹其实就是一个前缀)
String prefix = "dev/";
String folderKey = prefix.concat(uploadKey);
PutObjectRequest putObjectRequest = PutObjectRequest.builder().bucket(AwsConfig.BUCKET_NAME).key(folderKey).build();
s3Client.putObject(putObjectRequest, RequestBody.fromBytes(file));
return true;
}catch (S3Exception e){
System.err.println(e.getMessage());
return false;
}
}
/**
* s3文件预览
* @param uploadKey
*/
public static String DownloadFromS3(String uploadKey) {
BASE64Encoder encoder = new BASE64Encoder();
String prefix = "dev/";
String key = prefix.concat(uploadKey);
GetObjectRequest objectRequest = GetObjectRequest
.builder()
.key(key)
.bucket(AwsConfig.BUCKET_NAME)
.build();
ResponseBytes<GetObjectResponse> objectBytes = s3Client.getObjectAsBytes(objectRequest);
byte[] data = objectBytes.asByteArray();
// 转换成base64文件流,用于前端数据解析
return encoder.encodeBuffer(data).trim();
}
/**
* s3文件下载
* @param uploadKey
*/
public static void DownloadFromS3(HttpServletRequest request, HttpServletResponse response, String uploadKey) {
String prefix = "dev/";
// S3上存储的key
String key = prefix.concat(uploadKey);
GetObjectRequest objectRequest = GetObjectRequest
.builder()
.key(key)
.bucket(AwsConfig.BUCKET_NAME)
.build();
ResponseBytes<GetObjectResponse> objectBytes = s3Client.getObjectAsBytes(objectRequest);
InputStream inputStream = objectBytes.asInputStream();
BufferedInputStream bufInputStream = new BufferedInputStream(inputStream);
OutputStream out = null;
try {
// 文件名称
String fileName = "XXXXXX";
response.setContentType("application/force-download");
response.setHeader("fileName", URLEncoder.encode(fileName, "UTF-8"));
response.addHeader("Content-Disposition", "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
out = response.getOutputStream();
byte[] buf = new byte[1024];
int len;
while ((len = bufInputStream.read(buf)) > 0) {
out.write(buf, 0, len);
}
response.flushBuffer();
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* s3删除文件
* @param uploadKey
* @return
*/
public static boolean deleteFromS3(String uploadKey){
try {
String key = "dev/" + uploadKey;
DeleteObjectRequest deleteObjectRequest = DeleteObjectRequest.builder().bucket(AwsConfig.BUCKET_NAME).key(key).build();
DeleteObjectResponse deleteObjectResponse = s3Client.deleteObject(deleteObjectRequest);
return true;
}catch (S3Exception e){
System.err.println(e.getMessage());
return false;
}
}
/**
* 获取桶里所有的文件
*/
public static JSONArray ListBucketObjects() {
JSONArray jar = new JSONArray();
try {
ListObjectsRequest listObjects = ListObjectsRequest
.builder()
.bucket(AwsConfig.BUCKET_NAME)
.build();
ListObjectsResponse res = s3Client.listObjects(listObjects);
List<S3Object> objects = res.contents();
for (ListIterator iterVals = objects.listIterator(); iterVals.hasNext(); ) {
JSONObject job = new JSONObject();
S3Object myValue = (S3Object) iterVals.next();
System.out.print("\n The name of the key is " + myValue.key());
job.put("name",myValue.key());
System.out.print("\n The object is " + calKb(myValue.size()) + " KBs");
job.put("size",calKb(myValue.size())+" KBs");
System.out.print("\n The owner is " + myValue.owner());
jar.add(job);
}
} catch (S3Exception e) {
System.err.println(e.awsErrorDetails().errorMessage());
jar.add(e.awsErrorDetails().errorMessage());
System.exit(1);
}
return jar;
}
//文件大小
private static long calKb(Long val) {
return val/1024;
}
}