使用“上传"将文本文件的内容上传到存储器中的字符串. Vaadin 14中的小部件 [英] Uploading contents of a text file to a string in memory using the "Upload" widget in Vaadin 14

查看:104
本文介绍了使用“上传"将文本文件的内容上传到存储器中的字符串. Vaadin 14中的小部件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道Vaadin 14为该组件提供了 Upload 组件.用户可以选择要上传的文件,也可以拖放文件.

I know Vaadin 14 offers the Upload component for the user to either pick a file(s) to upload or to drag-and-drop file(s).

但是我不确定如何使用它.我希望将Web浏览器机器上的纯文本文件的内容作为

But I am not sure how to use it. I want the contents of a plain text file on the web browser’s machine to load into memory as a String or CharSequence on the server machine.

尽管该组件的描述页面上有一些示例,但我可以使用一个完整而最少的示例来加载纯文本.

While the description page for that component has some examples, I could use a complete yet minimal example of loading plain text.

推荐答案

以下是Vaadin 14.1.0.alpha3中的示例视图.我不是Upload专家,所以可能有更好的方法,但这似乎行得通.

Here is an example view in Vaadin 14.1.0.alpha3. I am not an expert on Upload, so there may be better approaches, but this seems to be working.

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

Notice the @Route annotation, and adjust to suit your own app.

Upload 组件是显示在您的网页上的可视窗口小部件,邀请用户拖放文件或使用文件选择对话框.我们添加了一个匿名侦听器对象(在此用lambda语法定义),当用户这样做时将被调用. FinishedEvent 对象作为要处理的文件的句柄传递给我们的侦听器.

The Upload component is a visual widget that appears on your web page, inviting the user to drag-and-drop files(s) or to use a file-picker dialog. We add an anonymous listener object, defined here in lambda syntax, to be invoked when the user does so. A FinishedEvent object is passed to our listener as our handle for the file(s) being uploaded.

接收上载八位位组的对象是Vaadin

The object receiving the uploaded octets is any implementation of the Vaadin Receiver interface. To load a single file into memory, use MemoryBuffer implementation. By passing a MemoryBuffer instance to our Upload instance, we are designating a place for the uploaded octets to go as they arrive on the server.

我们使用

We use an InputStream to manage the flow of arriving octets. In this example we read the arriving octets one-by-one. Alternatively, there are ways to read many octets together.

我们的InputStream将每个八位位组读取为int,其值的范围是0-255(包括0-255).值-1是输入流已结束的信号.因此,我们在while循环中收集这些int值,直到出现负数为止.

Our InputStream reads each octet as an int with a value in the range from 0-255 inclusive. A value of -1 is a signal the stream of inputs has ended. So we collect these int values in a while loop until a negative one appears.

我们使用 try-with-resources 语法来自动关闭 InputStream,它将字节从客户端加载到服务器.

We use try-with-resources syntax to automatically close the InputStream that loads bytes from the client to the server.

我们在 ByteArrayOutputStream .下一步是弄清那些收集的八位位组.这里没有魔术.您必须知道预期的内容,例如纯文本与格式化文本与 PDF .在此示例中,我们希望使用纯文本.对于文本,我们必须知道字符编码,例如 ASCII

We collect the arriving octets in a ByteArrayOutputStream. The next step is making sense of those collected octets. There is no magic here. You must know the intended content such as plain text versus formatted text versus tab-delimited data versus binary data versus document format like PDF. In this example, we expect plain text. And for text we must know the character encoding such as ASCII, UTF-8, or the legacy Windows-1252 encoding. In our case, we expect UTF-8 encoding. So we put this together by instantiating a new String object, passing to the constructor our collect octets and an enum object signifying our expectation of UTF-8: new String( bytesReceived.toByteArray() , StandardCharsets.UTF_8 ).

使用新的String,通过实例化HTML段落,将文件内容回显给用户.

With our new String in hand, we echo back to the user the contents of the file by instantiating an HTML paragraph.

这是整个示例类.

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.因此,可以将我们上面的代码块转换为单行代码.调用静态方法


We can simplify the code above. Vaadin 14.1 comes bundled with Apache Commons IO 2.5 library. That library has a convenience method for taking an InputStream and producing a String. So can turn a chunk of our code above into one-liner. Call static method org.apache.commons.io.IOUtils.toString. Pass the input stream, and specify the expected character encoding.

修改后的代码:

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.
    }
}


注意事项:上面的示例是您所要求的基本知识.我们没有进行任何错误处理,也没有对用户取消中途上传做出反应.


Caveat: The examples above are bare-bones minimal, as you asked. We have not done any error-handling nor react to the user canceling an upload mid-stream.

您可以通过阅读

You may learn more by reading the source code of the Upload component’s demo page provided by the Vaadin Ltd company.

并阅读有关 Upload 在Vaadin Flow中如何工作的详细信息, 由Matti Tahvonen上传和下载,输入和输出 .

And read this detailed post about how Upload works in Vaadin Flow, Uploads and downloads, inputs and outputs by Matti Tahvonen.

这篇关于使用“上传"将文本文件的内容上传到存储器中的字符串. Vaadin 14中的小部件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆