В настоящее время многие приложения предоставляют пользователям доступ для загрузки изображений, аватаров, аудио- или видеофайлов и т.д. Чаще всего разработчики предпочитают хранить эти данные в других облачных сервисах.
Работая над одним из моих личных проектов – Tabata – Фитнес-приложение , я разработал административный инструмент для управления данными об упражнениях в базе данных. Я сделал это, используя приятную комбинацию Spring Boot и Рамки Vaadin . Это конечный результат:
Чтобы загружать видео с упражнениями непосредственно в AWS S3 без использования консоли AWS, но с моей собственной административной панелью, я разработал пользовательский компонент на основе официального компонента загрузки Vaadin .
Вот как я это сделал.
Этот пост в блоге состоит из двух частей:
- Настройте службу Amazon для предоставления доступа только к одному приложению в определенном сегменте S3 .
- Java-код для программной загрузки файла в корзину S3 .
1. Создать учетную запись AWS
Вы можете создать его здесь
2. Создать корзину S3
В меню Службы в разделе Хранилище найдите S3:
Нажмите кнопку Создать корзину . В появившемся диалоговом окне введите имя вашей корзины, выберите ближайший к вам (или вашим потенциальным посетителям) регион и нажмите Создать .
3. Создать пользователя IAM
По соображениям безопасности мы создадим нового пользователя IAM (который будет нашим будущим приложением) и дадим разрешения только для приложения на доступ к созданному ведру.
В меню “Службы” выберите “Я ЕСТЬ”, а затем “Пользователи” в разделе “Управление доступом”. Пресса Добавить пользователя .
Введите имя пользователя и проверьте Программный доступ в разделе “Тип доступа”.
Пресса Следующий: Разрешения . Затем нажмите Прикреплять существующие политики напрямую и Создайте политику .
Выберите вкладку JSON, затем скопируйте и вставьте объект JSON из официальных документов AWS . Не забудьте изменить текстовый заполнитель в примере политики на свое собственное имя корзины.
Пресса Обзор политики . Введите название политики, описание (необязательно) и нажмите Создать политику .
Вернуться к Добавьте вкладку пользователя в браузере, обновите страницу и найдите в списке политик нашу созданную политику.
Пресса Далее: Теги , Далее: Просмотрите и, наконец, Создайте пользователя . Теперь вы можете увидеть учетные данные пользователя. Скачайте csv-файл, чтобы не потерять учетные данные, так как они нам скоро понадобятся.
Наша настройка AWS завершена. Давайте начнем кодировать!
4. Начать проект Vaadin
Самый удобный способ запустить проект Vaadin – использовать Vaadin Starter .
Скачайте, распакуйте папку и откройте ее в вашей любимой среде разработки.
Это базовый проект Vaadin, но это полностью работающее приложение (и это PWA по умолчанию).
Удалите все демонстрационные материалы: GreetService.java и все внутри MainViev.class конструктор.
5. Создать пользовательский компонент загрузки
Создавать UploadS3.java класс:
public class UploadS3 extends Div { private final MemoryBuffer buffer; private final Upload upload; public UploadS3() { buffer = new MemoryBuffer(); upload = new Upload(buffer); add(upload); } }
Затем добавьте этот пользовательский компонент в класс MainView:
@Route @CssImport("./styles/shared-styles.css") public class MainView extends VerticalLayout { public MainView() { addClassName("centered-content"); UploadS3 upload = new UploadS3(); add(upload); } }
Запустите проект и перейдите в браузере на локальный хост: 8080 (или любой другой порт, который вы определили в application.properties, я предпочитаю использовать порт 9999):
Мы видим компонент загрузки Vaadin по умолчанию.
6. Настройка клиента Amazon
Прежде всего, добавьте зависимость aws-java-sdk в pom.xml .
com.amazonaws aws-java-sdk 1.11.728
Затем в файле application.properties создайте пользовательские реквизиты для учетных данных AWS и вставьте значение Идентификатор ключа доступа и Секретный ключ доступа из загруженного ранее файла credentials.csv. Кроме того, добавьте свойство с именем созданной корзины S3.
aws.accessKey=XXXXXXXXXXX aws.secretKey=XXXXXXXXXXXXXXXXXXXXXXXX aws.s3bucket.name=vaadin-upload
Затем введите значения этих свойств в конструктор класса Main View и передайте их компоненту UploadS3.
public MainView(@Value("${aws.accessKey}") String accessKey, @Value("${aws.secretKey}") String secretKey, @Value("${aws.s3bucket.name}") String bucketName) { addClassName("centered-content"); UploadS3 upload = new UploadS3(accessKey, secretKey, bucketName); add(upload); }
В классе Загрузки 3 инициализируйте клиент AmazonS3 с предоставленными учетными данными. Итак, на данный момент код компонента UploadS3 выглядит так:
public class UploadS3 extends Div { private final MemoryBuffer buffer; private final Upload upload; private AmazonS3 s3client; private final String accessKey; private final String secretKey; private final String bucketName; public UploadS3(String accessKey, String secretKey, String bucketName) { this.buffer = new MemoryBuffer(); this.upload = new Upload(buffer); this.accessKey = accessKey; this.secretKey = secretKey; this.bucketName = bucketName; initAWSClient(); add(upload); } private void initAWSClient() { AWSCredentials credentials = new BasicAWSCredentials(this.accessKey, this.secretKey); this.s3client = AmazonS3ClientBuilder.standard() .withCredentials(new AWSStaticCredentialsProvider(credentials)) .withRegion(Regions.EU_CENTRAL_1) .build(); } }
Теперь нам нужно добавить функциональность для загрузки файла в корзину S3. Для этого создайте следующий метод в классе UploadS3:
... private String objectKey; ... private void uploadFile() { upload.addSucceededListener(event-> { try { InputStream is = buffer.getInputStream(); File tempFile = new File(event.getFileName()); FileUtils.copyInputStreamToFile(is, tempFile); objectKey = tempFile.getName(); s3client.putObject(new PutObjectRequest(bucketName, objectKey, tempFile)); if(tempFile.exists()) { tempFile.delete(); } } catch (AmazonServiceException | IOException ex) { ex.printStackTrace(); } }); }
Этот метод создает временный файл, в который копируется входной поток из компонента загрузки Vaadin. Затем этот файл загружается в корзину S3 и после этого удаляется.
Поскольку этот метод является прослушивателем событий, мы вызовем его в конструкторе класса UploadS 3.
public UploadS3(String accessKey, String secretKey, String bucketName) { this.buffer = new MemoryBuffer(); this.upload = new Upload(buffer); this.accessKey = accessKey; this.secretKey = secretKey; this.bucketName = bucketName; initAWSClient(); uploadFile(); add(upload); }
Давайте проверим то, что мы разработали!
Запустите приложение и откройте его в браузере.
Похоже, файл успешно загружен. Но давайте проверим это в консоли S3.
Да! Файл находится в ведре!
Если вы пытаетесь загрузить файл размером более 1 МБ и получаете сообщение об ошибке
org.apache.tomcat.util.http.fileupload.FileUploadBase$FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes.
просто увеличьте лимит следующих свойств в файле application.properties:
spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=10MB
Помните, когда мы настраивали политику разрешений для корзины S3, мы устанавливали только программный доступ и только для нашего приложения. Давайте проверим это!
Во-первых, давайте попробуем открыть загруженный файл (в нашем случае изображение) по его URL-адресу, который мы получим программно.
Для этого нам нужно:
- добавьте компонент текстового поля в Основной вид класс, передайте его в Файл загрузки способ загрузки компонента 3
public MainView(@Value("${aws.accessKey}") String accessKey, @Value("${aws.secretKey}") String secretKey, @Value("${aws.s3bucket.name}") String bucketName) { ... TextField link = new TextField("Link"); link.setWidthFull(); ... upload.uploadFile(link); ... add(upload, link); }
- внутри Загрузочный файл способ Загрузки 3 класс устанавливает значение URL загруженного файла в переданное текстовое поле
public void uploadFile(TextField link) { upload.addSucceededListener(event-> { ... link.setValue(s3client.getUrl(bucketName, objectKey).toString()); ... }); }
Теперь, когда мы загружаем файл, мы сразу же получаем его URL-адрес.
Но если мы скопируем и вставим этот URL-адрес в адресную строку браузера, мы получим сообщение об ошибке:
Доступ запрещен! Мы не можем получить картину, и это прекрасно!
Что, если мы попытаемся получить его программно?
Для этого нам нужно создать метод в классе UploadS 3 , который загрузит загруженное изображение из корзины S3, преобразует его содержимое в входной поток и вернет массив байтов :
public byte[] downloadImage() { byte[] imageBytes = new byte[0]; S3Object s3object = s3client.getObject(bucketName, objectKey); S3ObjectInputStream inputStream = s3object.getObjectContent(); try { imageBytes = IOUtils.toByteArray(inputStream); } catch (IOException e) { e.printStackTrace(); } return imageBytes; }
А затем в классе MainView давайте добавим Изображение компонент, который покажет изображение после его загрузки (и загрузки):
... private final Image image; ... public MainView(@Value("${aws.accessKey}") String accessKey, @Value("${aws.secretKey}") String secretKey, @Value("${aws.s3bucket.name}") String bucketName) { ... image = new Image("", "image"); link.addValueChangeListener(e -> { byte[] imageBytes = upload.downloadImage(); StreamResource resource = new StreamResource("image", () -> new ByteArrayInputStream(imageBytes)); image.setSrc(resource); add(image); }); ... }
Запустите приложение и протестируйте его:
Да, мы можем получить доступ к изображению через наше приложение!
И это все! В этом сообщении в блоге я описал пошаговый процесс настройки корзины Amazon S3 для частного доступа, загрузки файла в корзину с использованием Java и платформы Vaadin, а затем проверки разрешения на частный доступ.
Полный исходный код проекта доступен в этот репозиторий GitHub
Первоначально опубликовано на мой личный блог
Оригинал: “https://dev.to/ramonak/how-to-upload-a-file-to-aws-s3-in-java-using-vaadin-framework-1m2m”