3.5.2.1.16. 多文件上传控件

API 文档

FileMultiUploadField 组件允许用户把文件上传到服务器。这个组件是个按钮;用户点击时,系统自带的文件选择器会弹出,此时用户可以选择多个文件来上传。

gui multipleUpload

该组件对应的 XML 名称: multiUpload

下面是一个使用 FileMultiUploadField 的示例。

  • 在界面的 XML 描述中声明这个组件:

    1. <multiUpload id="multiUploadField" caption="Upload Many"/>
  • 在界面控制器中,需要注入该组件本身,还需要注入 FileUploadingAPIDataManager 这两个接口。

    1. @Inject
    2. private FileMultiUploadField multiUploadField;
    3. @Inject
    4. private FileUploadingAPI fileUploadingAPI;
    5. @Inject
    6. private Notifications notifications;
    7. @Inject
    8. private DataManager dataManager;
    9. @Subscribe
    10. protected void onInit(InitEvent event) { (1)
    11. multiUploadField.addQueueUploadCompleteListener(queueUploadCompleteEvent -> { (2)
    12. for (Map.Entry<UUID, String> entry : multiUploadField.getUploadsMap().entrySet()) { (3)
    13. UUID fileId = entry.getKey();
    14. String fileName = entry.getValue();
    15. FileDescriptor fd = fileUploadingAPI.getFileDescriptor(fileId, fileName); (4)
    16. try {
    17. fileUploadingAPI.putFileIntoStorage(fileId, fd); (5)
    18. } catch (FileStorageException e) {
    19. throw new RuntimeException("Error saving file to FileStorage", e);
    20. }
    21. dataManager.commit(fd); (6)
    22. }
    23. notifications.create()
    24. .withCaption("Uploaded files: " + multiUploadField.getUploadsMap().values())
    25. .show();
    26. multiUploadField.clearUploads(); (7)
    27. });
    28. multiUploadField.addFileUploadErrorListener(queueFileUploadErrorEvent -> {
    29. notifications.create()
    30. .withCaption("File upload error")
    31. .show();
    32. });
    33. }
    1onInit() 方法里面,添加了事件监听器,这样可以在文件上传成功或者出错时做出反馈。
    2该组件将所有选择的文件上传到客户端层(client tier) 的临时存储(temporary storage)并且调用通过 addQueueUploadCompleteListener() 方法添加的监听器。
    3在这个监听器里面,会调用 FileMultiUploadField.getUploadsMap() 方法获得临时存储的文件标识和文件名映射关系的 map。
    4然后,通过调用 FileUploadingAPI.getFileDescriptor() 为每一条 map 记录创建相应的 FileDescriptor 对象。 com.haulmont.cuba.core.entity.FileDescriptor (别跟 java.io.FileDescriptor 混淆了) 是一个持久化实体,唯一定义一个上传的文件,并且也用这个类从系统下载文件。
    5FileUploadingAPI.putFileIntoStorage() 方法用来把文件从客户端层的临时存储移动到 FileStorage。这个方法的参数是临时存储中文件的标识符和对应的 FileDescriptor 对象。
    6在将文件上传到 FileStorage 之后,通过调用 DataManager.commit() 方法将 FileDescriptor 实例存到数据库。这个方法的返回值可以用来设置给一个实体的属性,这个属性关联此文件。这里,FileDescriptor 简单的保存在数据库。上传的文件可以通过 Administration > External Files 界面查看。
    7完成整个上传过程之后,文件列表需要通过调用 clearUploads() 方法清空以便下一次上传再使用。

下面列出能跟踪上传进度的监听器:

  • FileUploadErrorListener
  • FileUploadStartListener
  • FileUploadFinishListener
  • QueueUploadCompleteListener

最大可上传的文件大小是由 cuba.maxUploadSizeMb 应用程序属性定义的,默认是 20MB。如果用户选择了更大的文件的话,会有相应的提示信息,并且中断上传过程。

multiUpload 属性:

  • accept XML 属性 (或者相应的 setAccept() 方法) 用来设置文件选择对话框里面的文件类型掩码,但是用户还是可以选择“所有文件”来上传任意文件。

    这个属性的值需要是以英文逗号分隔的文件后缀名,比如:*.jpg,*.png

  • fileSizeLimit XML 属性 (或者相应的 setFileSizeLimit() 方法) 用来设置最大允许上传的文件大小。这个设置是针对每一个文件都有效的。

    1. <multiUpload id="multiUploadField" fileSizeLimit="200000"/>
  • permittedExtensions XML 属性 (或者相应的 setPermittedExtensions() 方法) 设置允许的文件扩展名白名单。

    这个属性的值需要是字符串的集合,其中每个字符串是以 . 开头的允许的文件扩展名,比如:

    1. uploadField.setPermittedExtensions(Sets.newHashSet(".png", ".jpg"));
  • dropZone XML 属性允许设置一个特殊的 BoxLayout 用来作为从浏览器外部拖拽文件可以放置的目标容器区域。如果这个容器的样式没有特殊设置,当文件被拖拽到这块区域的时候,这个容器会被高亮显示,否则目标区域不会显示。

参考 加载和显示图片 有更多复杂的使用上传文件的例子。


multiUpload 的属性

accept - align - caption - captionAsHtml - css - description - descriptionAsHtml - dropZone - enable - fileSizeLimit - height - box.expandRatio - icon - id - pasteZone - permittedExtensions - stylename - tabIndex - visible - width

multiUpload 监听器

FileUploadErrorListener - FileUploadFinishListener - FileUploadStartListener - QueueUploadCompleteListener