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); ListgetAllTodos(); }
Интерфейс 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 Mapmetadata = 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”