В рамках данного руководства мы рассмотрим пример взаимодействия с файловым хранилищем Amazon S3 с помощью AWS SDK.
S3 – это крайне надежный и в то же время, крайне простой в работе сервис. В S3 мы работаем с так называемыми buckets (корзины), каждый их которых содержит файлы внутри. Эти файлы могут быть получены как через REST API, так и с помощью SOAP.
Перед началом работы по этому руководству необходимо выполнить следующие подготовительные шаги:
- Создать аккаунт на AWS Console
- Сгенерировать AWS Secret Key + Access Key с помощью сервиса IAM
После того как вы получите данные для подключения мы можем переходить к созданию проекта.
- Создайте новый gradle проект с помощью сайта Spring Inializr
2. Разархивируйте и откройте новый проект
3. Далее нам необходимо добавить зависимость AWS SDK в файл gradle.build
implementation group: 'com.amazonaws', name: 'aws-java-sdk', version: '1.12.52'
Теперь наш gradle.build файл имеет следующий вид:
plugins {
id 'org.springframework.boot' version '2.5.4'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
}
group = 'net.proselyte'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'
configurations {
compileOnly {
extendsFrom annotationProcessor
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'com.amazonaws:aws-java-sdk:1.12.52'
}
test {
useJUnitPlatform()
}
4. Создадим конфигурационный класс S3Config:
package net.proselyte.awss3.config;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class S3Config {
@Bean
public AmazonS3 s3client() {
AWSCredentials credentials = new BasicAWSCredentials(
"<AWS_ACCESS_KEY>",
"<AWS_SECRET_KEY>"
);
return AmazonS3ClientBuilder
.standard()
.withCredentials(new AWSStaticCredentialsProvider(credentials))
.withRegion(Regions.US_EAST_1)
.build();
}
}
Здесь AWS_ACCESS_KEY и AWS_SCRECT_KEY – это данные, которые были сгенерированы в AWS IAM.
5. Создание бакета:
Реализуем класс S3Service, в котором у нас будет метод createBucket
package net.proselyte.awss3.service;
import com.amazonaws.services.s3.AmazonS3;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
@Slf4j
@Service
@RequiredArgsConstructor
public class S3Service {
private final AmazonS3 s3client;
public void createBucket() {
String bucketName = "proselytetutorial";
if (s3client.doesBucketExistV2(bucketName)) {
log.info("Bucket {} already exists, use a different name", bucketName);
return;
}
s3client.createBucket(bucketName);
}
}
И тестовый класс, в котором попробуем выполнить данный метод:
package net.proselyte.awss3.service;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class S3ServiceTest {
@Autowired
private S3Service s3Service;
@Test
public void testCreateBucket() {
s3Service.createBucket();
}
}
После выполнения данного метода мы можем перейти в консоль AWS S3 и проверить:
6. Получение списка бакетов:
public void listBuckets(){ List<Bucket> buckets = s3client.listBuckets(); log.info("buckets: {}", buckets); }
Также изменим тестовый класс:
package net.proselyte.awss3.service;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class S3ServiceTest {
@Autowired
private S3Service s3Service;
@Test
public void testCreateBucket() {
s3Service.createBucket();
}
@Test
public void testListBuckets(){
s3Service.listBuckets();
}
}
И выполним данный метод:2021-08-23 11:16:22.833 INFO 75184 --- [ Test worker] net.proselyte.awss3.service.S3Service : buckets: [S3Bucket [name=proselytetutorial, creationDate=Mon Aug 23 11:02:28 EEST 2021, owner=S3Owner [name=proselytear,id=9772ab74173a02e9806225483854a8e66cc29b04b140889afa18b7f4ef85df8b]]
7. Загрузка файла
Для загрузки файла добавим новый файл в директорию src/main/resources/proselyte.txt и добавим новый метод:
@SneakyThrows public void uploadFile() { String bucketName = "proselytetutorial"; ClassLoader loader = S3Service.class.getClassLoader(); File file = new File(loader.getResource("proselyte.txt").getFile()); s3client.putObject( bucketName, "proselyte.txt", file); }
И изменим тестовый класс:
@Test public void testUploadFile(){ s3Service.uploadFile(); }
После выполнения данного метода мы сможем увидеть файл в нашем бакете:
8. Получение файлов
Добавим новый метод в наш сервисный класс:
public void listFiles() { String bucketName = "proselytetutorial"; ObjectListing objects = s3client.listObjects(bucketName); for(S3ObjectSummary objectSummary : objects.getObjectSummaries()) { log.info("File name: {}", objectSummary.getKey()); } }
И добавим новый метод в текстовый класс:
@Test public void testListFiles(){ s3Service.listFiles(); }
При выполнении этого метода мы увидим в консоли:
2021-08-23 12:15:11.815 INFO 976 --- [ Test worker] n.proselyte.awss3.service.S3ServiceTest : Started S3ServiceTest in 5.44 seconds (JVM running for 7.582)
2021-08-23 12:15:13.473 INFO 976 --- [ Test worker] net.proselyte.awss3.service.S3Service : File name: proselyte.txt
BUILD SUCCESSFUL in 14s
9. Скачивание файла
Кроме простого получение деталей объекта, мы можем также и скачать файл:
@SneakyThrows public void downloadFile() { String bucketName = "proselytetutorial"; S3Object s3object = s3client.getObject(bucketName, "proselyte.txt"); S3ObjectInputStream inputStream = s3object.getObjectContent(); File file = new File("<PUT_DESIRED_PATH_HERE>"); FileCopyUtils.copy(inputStream, new FileOutputStream(file)); }
При вызове метода downloadFile мы увидим, что файл, путь к которому был указан, был заполнен данными из файла на S3.
10. Удаление файла
Для удаления файла нам необходимо передать имя бакета и ключ файла:
public void deleteFile() {
String bucketName = "proselytetutorial";
s3client.deleteObject(bucketName,"proselyte.txt");
}
После вызова метода мы можем увидеть, что файл был удален из бакета:
На этом мы заканчиваем обзор работы с AWS S3 средствами SDK.
Более детально с возможностями AWS SDK S3 вы можете ознакомиться в официальной документации
Ссылка на исходный код проекта