3.5.2.1.16. FileMultiUploadField

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

gui multipleUpload

XML-имя компонента: multiUpload.

Рассмотрим пример использования компонента.

  • Объявляем компонент в XML-дескрипторе экрана:

    <multiUpload id="multiUploadField" caption="Upload Many"/>
  • В контроллере экрана инжектируем сам компонент, а также интерфейсы FileUploadingAPI и DataManager.

    @Inject
    private FileMultiUploadField multiUploadField;
    @Inject
    private FileUploadingAPI fileUploadingAPI;
    @Inject
    private Notifications notifications;
    @Inject
    private DataManager dataManager;
    
    @Subscribe
    protected void onInit(InitEvent event) { (1)
    
        multiUploadField.addQueueUploadCompleteListener(queueUploadCompleteEvent -> { (2)
            for (Map.Entry<UUID, String> entry : multiUploadField.getUploadsMap().entrySet()) { (3)
                UUID fileId = entry.getKey();
                String fileName = entry.getValue();
                FileDescriptor fd = fileUploadingAPI.getFileDescriptor(fileId, fileName); (4)
                try {
                    fileUploadingAPI.putFileIntoStorage(fileId, fd); (5)
                } catch (FileStorageException e) {
                    throw new RuntimeException("Error saving file to FileStorage", e);
                }
                dataManager.commit(fd); (6)
            }
            notifications.create()
                    .withCaption("Uploaded files: " + multiUploadField.getUploadsMap().values())
                    .show();
            multiUploadField.clearUploads(); (7)
        });
    
        multiUploadField.addFileUploadErrorListener(queueFileUploadErrorEvent -> {
            notifications.create()
                    .withCaption("File upload error")
                    .show();
        });
    }
    1 Затем в методе onInit() добавляем слушателей, которые будут реагировать на события успешной загрузки или ошибки:
    2 Компонент загружает выбранные файлы во временное хранилище клиентского уровня и вызывает слушатель, добавленный методом addQueueUploadCompleteListener().
    3 В данном слушателе вызовом метода getUploadsMap() у компонента можно получить мэп идентификаторов файлов во временном хранилище на имена файлов.
    4 Далее для каждого элемента мэп создается соответствующий объект FileDescriptor путем вызова FileUploadingAPI.getFileDescriptor(). Объект com.haulmont.cuba.core.entity.FileDescriptor (не путать с java.io.FileDescriptor) является персистентной сущностью, которая однозначно идентифицирует загруженный файл и впоследствии используется для выгрузки файла из системы.
    5 Метод FileUploadingAPI.putFileIntoStorage() используется для перемещения загружаемого файла из временного хранилища клиентского уровня в FileStorage. Параметрами этого метода являются идентификатор файла во временном хранилище и объект FileDescriptor.
    6 После загрузки файла в FileStorage выполняется сохранение экземпляра FileDescriptor в базе данных посредством вызова DataManager.commit(). Возвращаемый этим методом сохраненный экземпляр может быть установлен в атрибут какой-либо сущности предметной области, связанной с данным файлом. В данном же случае FileDescriptor просто сохраняется в базе данных. Соответствующий файл будет доступен через экран Administration > External Files.
    7 После обработки файлов необходимо очистить список файлов вызовом clearUploads() на случай повторной загрузки.

Ниже приведён список доступных слушателей для отслеживания процесса загрузки:

  • FileUploadErrorListener,

  • FileUploadStartListener,

  • FileUploadFinishListener,

  • QueueUploadCompleteListener.

Максимальный размер загружаемого файла определяется свойством приложения cuba.maxUploadSizeMb и по умолчанию равен 20MB. При выборе пользователем файла большего размера выдается соответствующее сообщение и загрузка прерывается.

Атибуты multiUpload:

  • XML-атрибут accept (и соответствующий метод setAccept()) может быть использован для установки маски расширений файлов в диалоге выбора файла. Пользователи будут иметь возможность выбрать "All files" и загрузить произвольные файлы.

    Значением атрибута должен быть список масок, разделенных запятыми. Например: *.jpg,*.png.

  • XML-атрибут fileSizeLimit (и соответствующий метод setFileSizeLimit()) может быть использован для установки максимально допустимого размера файла. Значением атрибута должно быть целое число для указания количества байт. Данный лимит устанавливает ограничение для каждого файла.

    <multiUpload id="multiUploadField" fileSizeLimit="200000"/>
  • XML-атрибут permittedExtensions (и соответствующий метод setPermittedExtensions()) может быть использован для установки "белого списка" допустимых расширений загружаемых файлов.

    Значением атрибута должен быть набор строк, в котором каждая строка - это допустимое расширение с лидирующей точкой. Например:

    uploadField.setPermittedExtensions(Sets.newHashSet(".png", ".jpg"));
  • XML-атрибут dropZone используется для указания BoxLayout, который будет использован в качестве целевой площадки для перетаскивания файлов извне браузера. Если стиль контейнера не переопределён, выбранный контейнер будет подсвечиваться, когда пользователь переносит над ним файлы, без наведения файла контейнер не отображается.

В руководстве Working with Images приведены более сложные примеры работы с загруженными файлами.