java - 使用 Vaadin 14 中的 "Upload"小部件将文本文件的内容上传到内存中的字符串

标签 java file-upload upload vaadin vaadin-flow

我知道 Vaadin 14 提供 Upload供用户选择要上传的文件或拖放文件的组件。

但是我不知道如何使用它。我希望将 Web 浏览器计算机上的纯文本文件的内容作为 String 加载到内存中。或CharSequence在服务器计算机上。

虽然该组件的描述页面有一些示例,但我可以使用加载纯文本的完整但最小的示例。

最佳答案

以下是 Vaadin 14.1.0.alpha3 中的示例 View 。我不是上传方面的专家,因此可能有更好的方法,但这似乎有效。

Screenshot of Vaadin "Upload" component in action.

注意@Route注释,并进行调整以适合您自己的应用程序。

Upload组件是出现在网页上的可视化小部件,邀请用户拖放文件或使用文件选择器对话框。我们添加一个匿名监听器对象,在此处以 lambda 语法定义,以便在用户执行此操作时调用。一个FinishedEvent对象作为正在上传的文件的句柄传递给我们的监听器。

接收上传八位字节的对象是 Vaadin Receiver 的任何实现界面。要将单个文件加载到内存中,请使用 MemoryBuffer执行。通过将 MemoryBuffer 实例传递给 Upload 实例,我们为上传的八位字节到达服务器时指定一个位置。

我们使用InputStream管理到达八位字节的流。在此示例中,我们逐一读取到达的八位字节。或者,有多种方法可以一起读取多个八位字节。

我们的InputStream将每个八位字节读取为int,其值范围为0-255(含)。 -1 值表示输入流已结束。因此,我们在 while 循环中收集这些 int 值,直到出现负数。

我们使用try-with-resources automatically close 的语法将字节从客户端加载到服务器的InputStream

我们将到达的八位字节收集在 ByteArrayOutputStream 中。下一步是理解这些收集到的八位字节。这里没有魔法。您必须知道想要的内容,例如plain text与格式化文本对比tab-delimited数据与二进制数据与文档格式,如 PDF 。在此示例中,我们期望纯文本。对于文本,我们必须知道字符编码,例如 ASCII , UTF-8 ,或遗产Windows-1252编码。在我们的例子中,我们期望 UTF-8 编码。因此,我们通过实例化一个新的 String 对象,将其组合在一起,将我们收集的八位字节和一个表示我们期望的 UTF-8 的枚举对象传递给构造函数: new String( bytesReceived.toByteArray() , StandardCharsets.UTF_8)

有了新的字符串,我们通过实例化 HTML 段落向用户回显文件的内容。

这是整个示例类。

package work.basil.example;

import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.upload.FinishedEvent;
import com.vaadin.flow.component.upload.Upload;
import com.vaadin.flow.component.upload.receivers.MemoryBuffer;
import com.vaadin.flow.router.Route;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

@Route ( "upload" )
public class UploadView extends VerticalLayout
{
    // Constructor
    public UploadView ( )
    {
        this.add( new H1( "Upload" ) );
        MemoryBuffer buffer = new MemoryBuffer();
        Upload upload = new Upload( buffer );  // Connect our server-side `Receiver` implementation to the client-side `Upload` widget.
        upload.addFinishedListener(
                ( FinishedEvent finishedEvent ) -> {  // Event fired when user uses the `Upload` widget on the web page.
                    try (  // Autoclosable interface used in try-with-resources syntax.
                           InputStream inputStream = buffer.getInputStream() ;
                    )
                    {
                        // read the contents of the buffer.
                        // https://www.baeldung.com/convert-input-stream-to-array-of-bytes
                        ByteArrayOutputStream bytesReceived = new ByteArrayOutputStream();
                        int content; // Represents each octet arriving on server from client.
                        while ( ( content = inputStream.read() ) != - 1 )  // The arriving octet is returned to us as an `int` in the range 0 to 255. A value of -1 signals end-of-stream. Blocks until data arrives or stream closes.
                        {
                            bytesReceived.write( content );  // Collect the arriving octets into a `ByteArrayOutputStream`.
                        }
                        // Parse the collected octets as being text in UTF-8 encoding.
                        String s = new String( bytesReceived.toByteArray() , StandardCharsets.UTF_8 );  // You must know the particular  character-encoding used in the file.
                        this.add( new Paragraph( s ) );  // Echo the file contents back to the user.
                        System.out.println( "s = " + s );
                    }
                    catch ( IOException e )
                    {
                        e.printStackTrace();
                    }
                }
        );
        this.add( upload );  // Make the `Upload` instance named `upload` appear on our Vaadin-produced web page.
    }
}
<小时/>

我们可以简化上面的代码。 Vaadin 14.1 捆绑 Apache Commons IO 2.5 库。该库有一个方便的方法来获取InputStream并生成String。因此可以将上面的一大块代码变成单行代码。调用静态方法org.apache.commons.io.IOUtils.toString 。传递输入流,并指定预期的字符编码。

修改后的代码:

package work.basil.example ;

import com.vaadin.flow.component.html.H1;
import com.vaadin.flow.component.html.Paragraph;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.upload.FinishedEvent;
import com.vaadin.flow.component.upload.Upload;
import com.vaadin.flow.component.upload.receivers.MemoryBuffer;
import com.vaadin.flow.router.PreserveOnRefresh;
import com.vaadin.flow.router.Route;
import org.apache.commons.io.IOUtils;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

@PreserveOnRefresh
@Route ( "upload" )
public class UploadView extends VerticalLayout
{
    // Constructor
    public UploadView ( )
    {
        this.add( new H1( "Upload" ) );
        MemoryBuffer buffer = new MemoryBuffer();
        Upload upload = new Upload( buffer );  // Connect our server-side `Receiver` implementation to the client-side `Upload` widget.
        upload.addFinishedListener(
                ( FinishedEvent finishedEvent ) -> {  // Event fired when user uses the `Upload` widget on the web page.

                    try (  // Autoclosable interface used in try-with-resources syntax.
                           InputStream inputStream = buffer.getInputStream() ;
                    )
                    {
                        // Read the data arriving in the buffer via the `InputStream` to produce a `String` object.
                        String s = IOUtils.toString( inputStream , StandardCharsets.UTF_8 );
                        this.add( new Paragraph( s ) );
                        System.out.println( "s = " + s );
                    }
                    catch ( IOException e )
                    {
                        e.printStackTrace();
                    }
                }
        );
        this.add( upload );  // Make the `Upload` instance named `upload` appear on our Vaadin-produced web page.
    }
}
<小时/>

警告:正如您所要求的,上面的示例是最基本的。我们没有进行任何错误处理,也没有对用户中途取消上传使用react。

<小时/>

您可以通过阅读 source code of the Upload component’s demo page 了解更多信息由 Vaadin Ltd 公司提供。

并阅读这篇关于 Vaadin Flow 中上传如何工作的详细文章,Uploads and downloads, inputs and outputs作者:马蒂·塔沃宁。

关于java - 使用 Vaadin 14 中的 "Upload"小部件将文本文件的内容上传到内存中的字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58493706/

相关文章:

java - 是否使用静态方法?

java - 将选项卡添加到 TabPane JavaFX

asp.net - AjaxFileUpload 回发 false

php - 通过 php 上传大文件 ( 0 - 5GB ) 的有效方法

c# - 从 FTP 上传文件和下载文件

java - Java 中的 WebSocket 编程 : client server communication issue

java - 线程的 String 字段上的 getter 和 setter 是否必须同步/

django - 需要帮助设置 django-filetransfers

php - 文章表上传图片后存储image_id