使用“上传"将文本文件的内容上传到存储器中的字符串. Vaadin 14中的小部件 [英] Uploading contents of a text file to a string in memory using the "Upload" widget in 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浏览器机器上的纯文本文件的内容作为 CharSequence
在服务器计算机上.
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.
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 , Windows-1252 编码.在我们的情况下,我们希望使用UTF-8编码.因此,我们通过实例化一个新的String
对象,将我们的收集八位字节和一个枚举对象传递给构造函数,以表示我们对UTF-8的期望:new String( bytesReceived.toByteArray() , StandardCharsets.UTF_8 )
.
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屋!