Amazon simple storage (Amazon S3) – это сервис, предлагаемый Amazon web services, который предлагает масштабируемое, безопасное и высокопроизводительное хранилище объектов. В этой статье будет рассказано о том, как загружать файлы в Amazon S3 с помощью Spring Boot.
Предпосылки
- Некоторые знания в Ява и Пружинный ботинок .
- Набор для разработки Java, установленный на вашем компьютере.
- Ваш любимый язь. Я использую Издание сообщества Intellij которое является бесплатным.
Учетная запись веб-служб Amazon
Прежде чем мы начнем создавать ваше приложение, перейдите в Консоль Amazon и создайте учетную запись. Вам будет предоставлен 12 месяцев бесплатного доступа к различным веб-сервисам Amazon, которые вы сможете использовать для тестирования различных сервисов Amazon.
После регистрации перейдите в Консоль Amazon и найдите Amazon S3 в поле поиска, представленном в консоли.
Ведро Amazon S3
После выбора Amazon S3 на шаге выше создайте новую корзину S3, которую мы будем использовать для хранения файлов, которые мы будем загружать из нашего приложения.
Назовите корзину как spring-amazon-storage и оставьте все остальные настройки по умолчанию, а затем создайте корзину.
Доступ и секретные ключи
Создайте новый ключ доступа из Мои учетные данные безопасности меню навигации, как показано на рисунке ниже. Скопируйте сгенерированный доступ и секретный ключ, поскольку мы будем использовать их для доступа к корзине из приложения, которое мы будем создавать.
Создание приложения
Мы будем использовать spring initializr для создания нашего приложения. Перейдите в spring initializr и создайте новое приложение Spring Boot, добавив h2 , spring boot devtools , spring data jpa и spring web в качестве зависимостей затем генерируют проект.
Распакуйте загруженный проект и откройте его в своей любимой среде разработки.
Добавление зависимости от Amazon SDK
Amazon SDK позволяет взаимодействовать с различными сервисами Amazon из наших приложений. В pom.xml файл добавляет зависимость Amazon SDK, как показано ниже.
com.amazonaws
aws-java-sdk
1.11.931
Структура проекта
config/ |--- AmazonConfig.java |--- BucketName.java controllers/ |--- TodoController.java domain/ |--- Todo.java repositories/ |--- TodoRepository.java service/ |--- FileStore.java |--- TodoService.java |--- TodoServiceImpl.java SpringAmazonApplication.java
Пакет конфигурации
В пакете конфигурации у нас есть два файла Java, один из которых аутентифицируется с помощью Amazon S3, а другой содержит имя корзины.
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
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 AmazonConfig {
@Bean
public AmazonS3 s3() {
AWSCredentials awsCredentials =
new BasicAWSCredentials("accessKey", "secretKey");
return AmazonS3ClientBuilder
.standard()
.withRegion("ap-south-1")
.withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
.build();
}
}
Приведенный выше класс Amazon Config снабжен аннотацией @Configuration , чтобы сделать его доступным для контекста Spring в качестве класса конфигурации. С учетными данными Amazon, которые мы получили из консоли Amazon ранее, мы будем аутентифицироваться в S3 с помощью AmazonS3ClientBuilder , доступного в Amazon-SDK, который мы добавили в наш pom.xml более поздний.
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum BucketName {
TODO_IMAGE("spring-amazon-storage");
private final String bucketName;
}
В перечислении Имя корзины выше мы передаем имя корзины, которое мы создали ранее в консоли Amazon. Корзина будет использоваться для хранения всех наших загруженных файлов.
@AllArgsConstructorаннотация создает конструктор симя корзиныпеременная в перечислении.@@Getterаннотация генерирует геттер для переменнойИмя корзиныв перечислении.
Доменный пакет
В этом пакете у нас есть модель Todo , которая представляет наши Задачи в базе данных.
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@Entity
public class Todo {
@Id
@GeneratedValue
private Long id;
private String title;
private String description;
private String imagePath;
private String imageFileName;
}
@Данныеаннотации генерируютполучатели,установщики,toStringиравныметодам для классаTodo.@AllArgsConstructorаннотация создает конструктор со всеми аргументами для классаTodo.@NoArgsConstructorаннотация создает конструктор без аргументов для классаTodo.@Builderаннотация создает шаблон построения для классаTodo.@@Сущностьаннотация заставляетДелатьобъект базы данных класса а.@Idаннотация помечает полеidкак первичный ключ в базе данных.@GeneratedValueаннотация автоматически увеличивает полеidвсякий раз, когда в базе данных сохраняется новоезадание.
Пакет репозитория
В этом пакете у нас есть класс репозитория, который расширяет интерфейс JPA CrudRepository , позволяющий выполнять различные запросы к базе данных.
public interface TodoRepository extends CrudRepository{ Todo findByTitle(String title); }
Пакет услуг
@AllArgsConstructor
@Service
public class FileStore {
private final AmazonS3 amazonS3;
public void upload(String path,
String fileName,
OptionalВ классе FileStore выше у нас есть логика, используемая для загрузки и выгрузки файлов с Amazon S3.
В методе upload мы передаем:
путь– это путь в корзине Amazon S3, где будет храниться файл.Имя файла– это фактическое имя загружаемого файла. Он будет использоваться в качестве ключа при загрузке файла с S3.дополнительные метаданныекарта содержит подробную информацию о файле, т.е. тип файла и размер файла.-
InputStreamсодержит фактический файл, который следует сохранить в Amazon S3.
ObjectMetadata objectMetadata = new ObjectMetadata();
optionalMetaData.ifPresent(map -> {
if (!map.isEmpty()) {
map.forEach(objectMetadata::addUserMetadata);
}
});
Приведенный выше блок кода перебирает дополнительные метаданные карту, добавляя всю информацию о файле в S3 objectMetaData .
amazon S3.putObject(путь, имя файла, входной поток, метаданные объекта);сохраняет файл в корзину Amazon S3.
В методе загрузки :
Объект S3.GetObject(путь, ключ);загружает файл по переданному пути и с именем файла, аналогичным ключу, переданному в методеGetObject.S3ObjectInputStream.getobjectcontent();получает входной поток от объекта, возвращенного из Amazon S3.Иутили.toByteArray(содержимое объекта)преобразует входной поток вмассив байтов, который может быть отправлен через API Restful.
public interface TodoService {
Todo saveTodo(String title, String description, MultipartFile file);
byte[] downloadTodoImage(Long id);
List getAllTodos();
}
Интерфейс To do Service выше содержит различные методы, которые мы будем реализовывать, чтобы иметь возможность сохранять и получать задачи .
@Service
@AllArgsConstructor
public class TodoServiceImpl implements TodoService {
private final FileStore fileStore;
private final TodoRepository repository;
@Override
public Todo saveTodo(String title, String description, MultipartFile file) {
//check if the file is empty
if (file.isEmpty()) {
throw new IllegalStateException("Cannot upload empty file");
}
//Check if the file is an image
if (!Arrays.asList(IMAGE_PNG.getMimeType(),
IMAGE_BMP.getMimeType(),
IMAGE_GIF.getMimeType(),
IMAGE_JPEG.getMimeType()).contains(file.getContentType())) {
throw new IllegalStateException("FIle uploaded is not an image");
}
//get file metadata
Map metadata = new HashMap<>();
metadata.put("Content-Type", file.getContentType());
metadata.put("Content-Length", String.valueOf(file.getSize()));
//Save Image in S3 and then save Todo in the database
String path = String.format("%s/%s", BucketName.TODO_IMAGE.getBucketName(), UUID.randomUUID());
String fileName = String.format("%s", file.getOriginalFilename());
try {
fileStore.upload(path, fileName, Optional.of(metadata), file.getInputStream());
} catch (IOException e) {
throw new IllegalStateException("Failed to upload file", e);
}
Todo todo = Todo.builder()
.description(description)
.title(title)
.imagePath(path)
.imageFileName(fileName)
.build();
repository.save(todo);
return repository.findByTitle(todo.getTitle());
}
@Override
public byte[] downloadTodoImage(Long id) {
Todo todo = repository.findById(id).get();
return fileStore.download(todo.getImagePath(), todo.getImageFileName());
}
@Override
public List getAllTodos() {
List todos = new ArrayList<>();
repository.findAll().forEach(todos::add);
return todos;
}
}
В TodoServiceImpl выше мы предоставляем реализацию методов сохранения и получения всех задач .
Комплект контроллеров
В этом пакете у нас есть класс TodoController , который обрабатывает входящие HTTP-запросы.
@RestController
@RequestMapping("api/v1/todo")
@AllArgsConstructor
@CrossOrigin("*")
public class TodoController {
TodoService service;
@GetMapping
public ResponseEntity> getTodos() {
return new ResponseEntity<>(service.getAllTodos(), HttpStatus.OK);
}
@PostMapping(
path = "",
consumes = MediaType.MULTIPART_FORM_DATA_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE
)
public ResponseEntity saveTodo(@RequestParam("title") String title,
@RequestParam("description") String description,
@RequestParam("file") MultipartFile file) {
return new ResponseEntity<>(service.saveTodo(title, description, file), HttpStatus.OK);
}
@GetMapping(value = "{id}/image/download")
public byte[] downloadTodoImage(@PathVariable("id") Long id) {
return service.downloadTodoImage(id);
}
}
Тестирование наших загрузок и загрузок из корзины S3
Вывод
Поздравляю! Теперь, когда вы узнали, как загружать и скачивать файлы с Amazon S3, продолжайте и реализуйте логику загрузки нескольких файлов в Amazon S3.
Найдите исходный код здесь .
Счастливого Кодирования!
Оригинал: “https://dev.to/paulodhiambo/how-to-upload-files-to-amazon-s3-in-spring-boot-2p40”