Рубрики
Без рубрики

Как загрузить файл в AWS S3 на Java (с использованием платформы Vaadin)

В настоящее время многие приложения предоставляют пользователям доступ для загрузки изображений, аватаров, аудио- или видеофайлов… Помечено java, vaadin, aws, учебное пособие.

В настоящее время многие приложения предоставляют пользователям доступ для загрузки изображений, аватаров, аудио- или видеофайлов и т.д. Чаще всего разработчики предпочитают хранить эти данные в других облачных сервисах.

Работая над одним из моих личных проектов – Tabata – Фитнес-приложение , я разработал административный инструмент для управления данными об упражнениях в базе данных. Я сделал это, используя приятную комбинацию Spring Boot и Рамки Vaadin . Это конечный результат:

Чтобы загружать видео с упражнениями непосредственно в AWS S3 без использования консоли AWS, но с моей собственной административной панелью, я разработал пользовательский компонент на основе официального компонента загрузки Vaadin .

Вот как я это сделал.

Этот пост в блоге состоит из двух частей:

  1. Настройте службу Amazon для предоставления доступа только к одному приложению в определенном сегменте S3 .
  2. 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”