Uploading Files

This section explains how upload files from the user’s computer using UI components. For information on how to upload files through REST API, see the Files API section.

File Upload Components

Jmix provides a set of UI components for uploading files. All of them contain a button that, when clicked, opens a file system dialog for choosing files. Here’s a quick rundown of the differences between the components. For complete details on each component, refer to their respective sections.

  • fileUploadField lets users select a single file and save it as a byte array to an entity attribute. Users can also access the file’s content directly from the component’s value without associating it with an entity.

  • fileStorageUploadField allows users to select a single file and save it to the file storage. The component’s value is a FileRef object. Users can link the component to an entity attribute of FileRef type to automatically save the file reference to the database.

  • upload lets users upload one or multiple files at once. It provides a base for handling file uploads but doesn’t directly interact with entities or storage systems.

Using TemporaryStorage

The FileStorageUploadField component has the fileStoragePutMode attribute with the default value IMMEDIATE. If you set it to MANUAL, the component uploads the file to the temporary storage in the file system of the application, and gives you full control over the uploaded file: you can transfer the file to the file storage as is, pre-process it, or do whatever you need with the file without saving it to the file storage at all.

The TemporaryStorage interface provides an API to create temporary files, save them to the file storage, or remove them.

Below is an example of using fileStorageUploadField in manual mode to transfer the uploaded file from temporary storage to the file storage.

<fileStorageUploadField id="fileField" fileStoragePutMode="MANUAL"/>
@ViewComponent
private FileStorageUploadField fileField;

@Autowired
private TemporaryStorage temporaryStorage;

@Subscribe("fileField")
public void onFileFieldFileUploadSucceeded(final FileUploadSucceededEvent<FileStorageUploadField> event) {
    if (event.getReceiver() instanceof FileTemporaryStorageBuffer buffer) {
        UUID fileId = buffer.getFileData().getFileInfo().getId();
        File file = temporaryStorage.getFile(fileId); (1)
        if (file != null) {
            FileRef fileRef = temporaryStorage.putFileIntoStorage(fileId, event.getFileName()); (2)
            fileField.setValue(fileRef);
        }
    }
}
1 Get local file from the temporary storage using identifier provided by the upload event.
2 Transfer local file to the file storage.

The putFileIntoStorage() method also removes the temporary local file.

If you only need to process the file locally without saving it to file storage, use the deleteFile() method of TemporaryStorage after working with the file, for example:

File file = temporaryStorage.getFile(fileId);
if (file != null) {
    processFile(file);
    temporaryStorage.deleteFile(fileId);
}

The temporary storage tends to accumulate files that were not deleted for various reasons. So it provides a JMX interface for removing such old unused files.

The MBean has the clearTempDirectory() method that removes all files from the temporary directory of the application (.jmix/temp by default) which are older than 2 days. You can call this method manually, or use a Quartz job to do it periodically. In a job, you should inject the TemporaryStorageManagementFacade bean and call its clearTempDirectory() method.