Docs

Documentation versions (currently viewingVaadin 24)
Documentation translations (currently viewingChinese)

本页面内容由官方文档(http://vaadin.com/docs)机器翻译而来,可能包含错误、不准确或表述不当之处。Vaadin不保证或声明该翻译内容的准确性、可靠性或时效性。

使用UploadHandler接收传入的数据流

使用UploadHandler接收传入的数据流。

要从客户端接收上传内容,需要注册一个[classname]UploadHandler,该处理器接受一个URL,用于处理接收的上传流。 推荐的上传文件方式是使用 Upload component,而本部分文档展示了更为定制化组件的使用方法。

要创建[classname]UploadHandler,需要实现[methodname]handleUploadRequest`来处理上传,或者使用提供的UploadHandlers之一。 现有的[classname]`UploadHandler`实现可以通过[classname]`UploadHandler`中的静态方法访问,例如`UploadHandler.toTempFile(SerializableBiConsumer<UploadMetadata, File> successHandler)

Note
当接收多部分上传时,[methodname]`handleUploadRequest`会针对上传中的每一个文件单独调用。

然后可以通过[classname]Element API,将其作为属性进行注册。

Source code
Java
List<File> outputFiles = new ArrayList<>(1);
UploadHandler uploadHandler = UploadHandler.toTempFile((uploadMetadata, file) -> outputFiles.add(file));

getElement().setAttribute("target", uploadHandler);

Upload元素可以由类型为`file`的[classname]`Input`和一个[classname]`Button`组成,[classname]`Button`通过JavaScript将文件发送到服务器。

Source code
Java
Span container = new Span();
Input input = new Input();
input.setType("file");

Button uploadButton = new Button("Upload",
    (event) -> event.getSource().getElement().executeJs("""
        const file = $0.files[0];
        if (!file) {
          alert("No file selected");
          return;
        }
        const formData = new FormData();
        formData.append("file", file);
        fetch(this.getAttribute("endpoint"), {
          method: "POST",
          body: formData
        }).then(response => {
          if (response.ok) {
            alert("Upload successful");
          } else {
            alert("Upload failed");
          }
        });
        """, input.getElement()));

InMemoryUploadHandler inMemoryUploadHandler = UploadHandler.inMemory(
    (uploadMetadata, bytes) -> {
        // 在此处处理已上传的数据
    });

uploadButton.getElement()
    .setAttribute("endpoint", inMemoryUploadHandler);

container.add(input, uploadButton);

另一种方式是执行表单操作,将数据上传到服务器。

步骤如下:

Source code
HTML
<iframe name="dummyFrame" id="dummyFrame" display="none"/>
<form method="post" enctype="multipart/form-data" action="Element.getAttribute('target')" target="dummyFrame">
  <input type="file" name="file"/>
  <input type="submit"/>
</form>
Note
dummyFrame iframe用于防止提交时页面跳转至action url。
Note
如需同时上传多个文件,请在文件类型输入中添加`multiple`属性,例如`<input type="file" name="file" multiple/>`。

通过element API可以这样实现:

Source code
Java
InMemoryUploadHandler inMemoryUploadHandler = UploadHandler.inMemory(
    (uploadMetadata, bytes) -> {
        // 在此处处理已上传的数据
    });

// 为提交动作生成占位iframe
IFrame dummy = new IFrame();
dummy.setName("dummy");
dummy.setId("dummy");
dummy.getStyle().set("display", "none");

// 使用element api设置表单
Element formElement = new Element("form").setAttribute("method", "post")
    .setAttribute("enctype", "multipart/form-data")
    .setAttribute("action", inMemoryUploadHandler)
    .setAttribute("target", "dummy");
Element files = new Element("input").setAttribute("type", "file")
    .setAttribute("name", "file");
Element submit = new Element("input").setAttribute("type", "submit");
formElement.appendChild(files).appendChild(submit);

add(dummy);
getElement().appendChild(formElement);

4482D0BF-E742-4FEA-A888-854B758FE576