fileStorageUploadField 文件存储上传

fileStorageUploadField 支持用户将文件上传至 Jmix 文件存储

  • XML 元素:fileStorageUploadField

  • Java 类:FileStorageUploadField

基本用法

这个组件可以包含标题、已上传文件的链接和一个上传按钮。当点击上传按钮的时候,会弹出标准的文件选择器,用户可以在这里选择需要上传的文件。

file storage upload basics

fileStorageUploadField 既可以 绑定实体属性,也可以不绑定数据。

下面的示例我们展示在没有数据绑定的情况下使用组件。可以用来直接处理上传的文件,而无需将其与任何 Jmix 实体关联。

<fileStorageUploadField id="fileRefField"
                        acceptedFileTypes=".xlsx, .xls"
                        fileStoragePutMode="MANUAL"
                        fileNameVisible="true"/>

可以直接在 FileUploadSucceededEvent 事件中处理上传的文件。

如需以字节数组的格式在实体属性保存文件,而不是 FileRef,那么请使用 fileUploadField 组件。

如需同时上传多个文件,请使用 upload 组件。

上传的文件会立即保存在默认的 FileStorage 中。如需以编程的方式控制文件的存储,可以使用 fileStoragePutMode 属性。

数据绑定

fileStorageUploadField 支持用户上传文件至 文件存储 并作为一个 FileRef 对象设置给实体属性。

下面例子中,User 实体的 picture 属性是 FileRef 类型。

@Column(name = "PICTURE", length = 1024)
private FileRef picture;
<data>
    <instance class="com.company.onboarding.entity.User" id="userDc">
        <fetchPlan extends="_base"/>
        <loader id="userDl"/>
    </instance>
</data>
<layout>
    <fileStorageUploadField dataContainer="userDc"
                            property="picture"
                            clearButtonVisible="true"
                            fileNameVisible="true"/>
</layout>

fileStorageUploadFielddataContainer 属性指定连接的数据容器;property 属性指定展示在 fileStorageUploadField 的实体属性名。

国际化

fileStorageUploadField 的所有标签和消息都可以配置。

file storage upload text attrs
  1. label 属性。

  2. uploadText 属性。

  3. requiredMessage 属性。

  4. fileNotSelectedText 属性。

  5. helperText 属性。

  6. fileTooBigText 属性。

  7. incorrectFileTypeText 属性。

  8. uploadDialogTitle 属性。

  9. remainingTimeText 属性。

  10. uploadDialogCancelText 属性。

  11. processingStatusText 属性。

connectingStatusText

设置当连接建立后在上传窗口展示的状态文本。

该属性可以是文本本身或者 消息包 中的一个键值。如果是消息包键值,则必须以 msg:// 开头。

fileNotSelectedText

设置当 fileNameVisible="true" 而文件还未上传时显示的文本。默认显示 "File is not selected(未选择文件)"。

该属性可以是文本本身或者 消息包 中的一个键值。如果是消息包键值,则必须以 msg:// 开头。

fileTooBigText

设置当文件大小超出 maxFileSize 设置的值后异常信息的文本。

该属性可以是文本本身或者 消息包 中的一个键值。如果是消息包键值,则必须以 msg:// 开头。

incorrectFileTypeText

设置当文件扩展名不包含在 acceptedFileTypes 属性时显示的消息。

该属性可以是文本本身或者 消息包 中的一个键值。如果是消息包键值,则必须以 msg:// 开头。

processingStatusText

设置当文件上传成功且处理完成后显示在上传窗口的状态文本。

该属性可以是文本本身或者 消息包 中的一个键值。如果是消息包键值,则必须以 msg:// 开头。

remainingTimeText

设置显示上传弹窗中剩余上传时间的文本。

该属性可以是文本本身或者 消息包 中的一个键值。如果是消息包键值,则必须以 msg:// 开头。

remainingTimeUnknownText

设置当无法计算剩余上传时间时上传弹窗中显示的文本。

该属性可以是文本本身或者 消息包 中的一个键值。如果是消息包键值,则必须以 msg:// 开头。

uploadDialogCancelText

设置上传弹窗中取消按钮的显示文本。

该属性可以是文本本身或者 消息包 中的一个键值。如果是消息包键值,则必须以 msg:// 开头。

uploadDialogTitle

设置当正在上传文件时上传弹窗的标题。

该属性可以是文本本身或者 消息包 中的一个键值。如果是消息包键值,则必须以 msg:// 开头。

uploadText

设置上传按钮的文本。

该属性可以是文本本身或者 消息包 中的一个键值。如果是消息包键值,则必须以 msg:// 开头。

XML 属性

acceptedFileTypes

指定服务器能接收的文件类型。文件格式使用 MIME 类型模式 或文件扩展名定义。

MIME 类型具有广泛的支持,而文件扩展名仅在某些浏览器支持,因此需要尽可能避免使用扩展名。
<fileStorageUploadField dataContainer="userDc"
                        property="picture"
                        acceptedFileTypes="image/png, .png"/>
acceptedFileTypes 属性能过滤系统文件选择对话框中的文件类型,确保用户只能选择允许的类型。

clearButtonAriaLabel

MDN

设置清空按钮的 aria-label 属性。

clearButtonVisible

设置是否在文件名后面显示清除按钮。仅当 fileNameVisible="true" 有效。

默认值是 false

dropAllowed

设置组件是否支持拖放文件进行上传。

默认值是 true

文件只能被拖放至组件的 Upload 按钮上。

fileNameVisible

fileNameVisible 属性设置是否在上传按钮旁边显示上传的文件名称。默认为 false

fileStorageName

设置上传文件保存的 FileStorage 名称。如果未设置,则使用默认的文件存储。

fileStoragePutMode

设置文件放入文件存储的模式。fileStoragePutMode 属性默认设置为 IMMEDIATE。如果设置为 MANUAL 值,则能以编程的方式控制文件的保存:

<fileStorageUploadField id="manuallyControlledField"
                        dataContainer="userDc"
                        property="picture"
                        clearButtonVisible="true"
                        fileNameVisible="true"
                        fileStoragePutMode="MANUAL"/>

视图控制器中,定义组件和 TemporaryStorage 接口。然后订阅文件上传成功或出错的 事件

@Autowired
private TemporaryStorage temporaryStorage;
@ViewComponent
private FileStorageUploadField manuallyControlledField;
@Autowired
private Notifications notifications;

@Subscribe("manuallyControlledField")
public void onManuallyControlledFieldFileUploadSucceeded(
        final FileUploadSucceededEvent<FileStorageUploadField> event) {
    Receiver receiver = event.getReceiver();
    if (receiver instanceof FileTemporaryStorageBuffer) {
        UUID fileId = ((FileTemporaryStorageBuffer) receiver)
                .getFileData().getFileInfo().getId();
        File file = temporaryStorage.getFile(fileId);

        if (file != null) {
            notifications.create("File is uploaded to temporary storage at "
                            + file.getAbsolutePath())
                    .show();
        }
        FileRef fileRef = temporaryStorage.putFileIntoStorage(fileId, event.getFileName());
        manuallyControlledField.setValue(fileRef);
        notifications.create("Uploaded file: "
                        + ((FileTemporaryStorageBuffer) receiver).getFileData().getFileName())
                .show();
    }
}

该组件将文件上传至临时存储之后,便会调用 FileUploadSucceedEvent 的监听器。

TemporaryStorage.putFileIntoStorage() 方法将上传的文件从临时客户端存储移至默认的 文件存储

在上传具有 MANUAL 模式的 FileStorageUploadField 字段后,不会自动触发 ComponentValueChangeEvent,因为 FileRef 的值只能在文件上传至永久文件存储后获得。

maxFileSize

设置允许上传文件的最大字节数。注意,这是一个客户端层面的约束,会在发送上传请求之前检查。

如果 MultipartProperties 可用,默认值从 MultipartProperties#getMaxFileSize() 获得,即 1Mb。如需提高应用程序中所有字段支持的最大文件大小,请使用 MultipartProperties#getMaxFileSize() 属性。

uploadIcon

设置上传按钮的图标。

事件和处理器

在 Jmix Studio 生成处理器桩代码时,可以使用 Jmix UI 组件面板的 Handlers 标签页或者视图类顶部面板的 Generate Handler 添加,也可以通过 CodeGenerate 菜单(Alt+Insert / Cmd+N)生成。

FileUploadFailedEvent

当产生 UploadFailedEvent 事件时,会触发 io.jmix.flowui.kit.component.upload.event.FileUploadFailedEvent。参考 Upload.addFailedListener(ComponentEventListener)

@Subscribe("manuallyControlledField")
public void onManuallyControlledFieldFileUploadFailed(
        final FileUploadFailedEvent<FileStorageUploadField> event) {
    notifications.create("File upload error")
            .show();
}

FileUploadFileRejectedEvent

当产生 UploadFileRejectedEvent 事件时,会触发 io.jmix.flowui.kit.component.upload.event.FileUploadFileRejectedEvent。参考 Upload.addFileRejectedListener(ComponentEventListener)

FileUploadFinishedEvent

当产生 UploadFinishedEvent 事件时,会触发 io.jmix.flowui.kit.component.upload.event.FileUploadFinishedEvent。参考 Upload.addFinishedListener(ComponentEventListener)

FileUploadProgressEvent

当产生 UploadProgressUpdateEvent 事件时,会触发 io.jmix.flowui.kit.component.upload.event.FileUploadProgressEvent。参考 Upload.addProgressListener(ComponentEventListener)

FileUploadStartedEvent

当产生 UploadStartedEvent 事件时,会触发 io.jmix.flowui.kit.component.upload.event.FileUploadStartedEvent。参考 Upload.addStartedListener(ComponentEventListener)

FileUploadSucceededEvent

当产生 UploadSucceededEvent 事件时,会触发 io.jmix.flowui.kit.component.upload.event.FileUploadSucceededEvent,表示上传文件已经成功接收。参考 Upload.addSucceededListener(ComponentEventListener)

下面是使用 fileStorageUploadField 上传 .xls.xlsx 文件的示例,文件在 FileUploadSucceededEvent 事件中处理。

@Subscribe("fileRefField")
public void onFileRefFieldFileUploadSucceeded(
        final FileUploadSucceededEvent<FileStorageUploadField> event) {
    if (event.getReceiver() instanceof FileTemporaryStorageBuffer buffer) {
        UUID fileId = buffer.getFileData().getFileInfo().getId();
        log.info("FileId: " + fileId);

        File file = temporaryStorage.getFile(fileId); (1)
        log.info("File from temp storage: " + file);
        try { (2)
            List<String> lines = FileUtils.readLines(file, StandardCharsets.UTF_8);
            for (String line : lines) {
                log.info("Read line: " + line);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        temporaryStorage.deleteFile(fileId); (3)
        log.info("File is deleted from temp storage: " + file);
    }
}
1 使用上传事件提供的 id 从 临时存储 获取文件。
2 处理文件数据。
3 删除上传的文件。在真实的应用程序中,这里可以使用 temporaryStorage.putFileIntoStorage() 方法将文件移至 FileStorage

fileStoragePutMode 的介绍中也有 FileUploadSucceededEvent 的示例。

XML 内部元素