Загрузка файлов
В этом разделе объясняется, как загружать файлы с компьютера пользователя с помощью компонентов пользовательского интерфейса. Сведения о том, как загружать файлы через REST API, см. в разделе Files API.
Компоненты загрузки файлов
Jmix предоставляет набор компонентов UI для загрузки файлов. Все они содержат кнопку, при нажатии которой открывается диалоговое окно файловой системы для выбора файлов. Ниже приводится краткое объяснение различий между компонентами. Полная информация о компонентах представлена в соответствующих разделах.
-
FileUploadField позволяет выбрать один файл и сохранить его как массив байтов в атрибуте сущности. Также вы можете получить содержимое файла прямо из значения компонента, не связывая его с сущностью.
-
FileStorageUploadField позволяет выбрать один файл и сохранить его в хранилище файлов. Значением компонента является объект
FileRef
. Вы можете связать этот компонент с атрибутом сущностиFileRef
типа для автоматического сохранения ссылки на файл в базе данных. -
FileMultiUploadField позволяет выбрать сразу несколько файлов и загрузить их во временное хранилище на сервере. Затем вы можете обработать их и/или перенести в постоянное файловое хранилище.
FileUploadField
и FileStorageUploadField
могут отображать имя загруженного файла рядом с кнопкой. Имя файла также служит ссылкой для скачивания.
FileUploadField
и FileStorageUploadField
могут иметь «зону перетаскивания» и «зону вставки» для загрузки файлов путем перетаскивания или вставки с клавиатуры.
Использование TemporaryStorage
Компонент FileStorageUploadField
имеет атрибут fileStoragePutMode со значением по умолчанию IMMEDIATE
. Если установить его в MANUAL
, компонент загружает файл во временное хранилище в файловой системе приложения и дает вам полный контроль над загруженным файлом. Его можно передать в файловое хранилище как есть, предварительно обработать его, а также сделать все, что вам нужно, вообще не сохраняя его в файловом хранилище.
То же самое и с компонентом FileMultiUploadField: он просто загружает файлы во временное хранилище и уведомляет ваш код о завершении загрузки.
Интерфейс TemporaryStorage
предоставляет API для создания временных файлов, сохранения их в хранилище файлов или их удаления.
Ниже приведен пример использования FileStorageUploadField
в ручном режиме для переноса загруженного файла из временного в файловое хранилище.
<fileStorageUpload id="fileField"
property="image"
fileStoragePutMode="MANUAL"/> (1)
1 | Установите для компонента fileStoragePutMode="MANUAL" . |
@Autowired
private FileStorageUploadField fileField;
@Autowired
private TemporaryStorage temporaryStorage;
@Subscribe("fileField")
public void onFileFieldFileUploadSucceed(SingleFileUploadField.FileUploadSucceedEvent event) {
File file = temporaryStorage.getFile(fileField.getFileId()); (1)
if (file != null) {
FileRef fileRef = temporaryStorage.putFileIntoStorage(fileField.getFileId(), event.getFileName()); (2)
fileField.setValue(fileRef);
}
}
1 | Получение локального файла из временного хранилища, используя идентификатор, указанный в поле. |
2 | Перенос локального файла в файловое хранилище. |
Метод putFileIntoStorage()
также удаляет временный локальный файл.
Если вам нужно только локально обработать файл, не сохраняя его в файловое хранилище, используйте метод deleteFile()
интерфейса TemporaryStorage
после работы с файлом, например:
File file = temporaryStorage.getFile(fileField.getFileId());
if (file != null) {
processFile(file);
temporaryStorage.deleteFile(fileField.getFileId());
}
Во временном хранилище накапливаются файлы, которые по разным причинам не были удалены. Поэтому он предоставляет JMX-интерфейс для удаления старых неиспользуемых файлов. Его можно найти по имени jmix.ui:type=TemporaryStorage на экране Administration → JMX Console. У MBean есть метод clearTempDirectory()
, который удаляет все файлы старше 2 дней из временного каталога приложения (.jmix/temp
по умолчанию). Вы можете вызывать этот метод вручную или периодически использовать задание Quartz. Для этого в задании нужно внедрить компонент TemporaryStorageManagementFacade
и вызвать его метод clearTempDirectory()
.