Загрузка содержимого текстового файла в строку в памяти с помощью виджета «Загрузка» в Vaadin 14 - PullRequest
1 голос
/ 21 октября 2019

Я знаю, что Vaadin 14 предлагает компонент Загрузка , чтобы пользователь мог выбрать файл (ы) для загрузки или перетащить файл (ы).

Но я не уверен, как его использовать. Я хочу, чтобы содержимое простого текстового файла на компьютере веб-браузера загружалось в память как String или CharSequence на сервере.

Хотя на странице описания этого компонента есть несколько примеров, я мог бы использовать полный, но минимальный пример загрузки простого текста.

1 Ответ

2 голосов
/ 21 октября 2019

Вот пример представления в Vaadin 14.1.0.alpha3. Я не эксперт по Upload, поэтому могут быть более подходящие подходы, но, похоже, это работает.

Screenshot of Vaadin

Обратите внимание на @Route аннотацию и настройку в соответствии с вашим собственным приложением.

Компонент Upload представляет собой визуальный виджет, который появляется на вашей веб-странице и предлагает пользователю перетащитьи перетащите файлы или использовать диалог выбора файлов. Мы добавляем анонимный объект прослушивателя, определенный здесь в лямбда-синтаксисе, который будет вызываться, когда пользователь делает это. Объект FinishedEvent передается нашему слушателю как наш дескриптор загружаемых файлов.

Объект, получающий загруженные октеты, является любой реализацией Vaadin Receiver интерфейс. Чтобы загрузить один файл в память, используйте реализацию MemoryBuffer. Передав экземпляр MemoryBuffer нашему экземпляру Upload, мы определяем место для загруженных октетов, когда они поступают на сервер.

Мы используем InputStream для управления потоком поступающих октетов. В этом примере мы читаем поступающие октеты один за другим. Кроме того, есть способы прочитать много октетов вместе.

Наш InputStream читает каждый октет как int со значением в диапазоне от 0 до 255 включительно. Значение -1 является сигналом окончания потока входов. Таким образом, мы собираем эти int значения в цикле while, пока не появится отрицательное значение.

Мы используем синтаксис try-with-resources , чтобы автоматически закрывать InputStream, который загружает байты с клиента на сервер.

Мы собираем поступающие октеты в ByteArrayOutputStream. Следующим шагом становится понимание этих собранных октетов. Здесь нет магии. Вы должны знать предполагаемое содержимое, например обычный текст в сравнении с форматированным текстом и данными с разделителями табуляции в сравнении с двоичными данными в сравнении с форматом документа, например PDF . В этом примере мы ожидаем простой текст. А для текста мы должны знать кодировку символов, такую ​​как ASCII , UTF-8 или устаревшую кодировку Windows-1252 . В нашем случае мы ожидаем кодирования UTF-8. Итак, мы соединили это, создав новый объект String, передав в конструктор наши октеты сбора и объект enum, обозначающий наше ожидание 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.
    }
}

Предупреждение: Приведенные выше примеры минимальны, как вы и просили. Мы не занимались обработкой ошибок и не реагировали на отмену пользователем промежуточного потока загрузки.


Вы можете узнать больше, прочитав исходный код демонстрационной страницы Upload компонента предоставлено компанией Vaadin Ltd.

И прочитайте этот подробный пост о том, как Загрузка работает в Vaadin Flow, Загрузка и выгрузка, ввод и вывод от Матти Тахвонена.

...