Как я могу получить содержимое файла в моем сервисе Vaadin?
Я хочу добавить кнопку загрузки в свое веб-приложение. В шаблоне HTML я добавил:
<link rel="import" href="../../../bower_components/vaadin-upload/src/vaadin-upload.html">
<h2 id="header-Upload">Upload</h2>
<vaadin-upload nodrop/>
Теперь я хочу получить поток в своем внутреннем процессе Vaadin. Этот поток может быть затем вставлен в базу данных.
Документация на https://vaadin.com/components/vaadin-upload/html-examples/upload-basic-demos не предоставляет эту информацию.
Я считаю, что я должен как-то связать StreamReceiver
к <vaadin-upload>
под вопросом, но я не уверен, как это сделать.
Я использую Vaadin Flow (версия 12).
Дополнительная информация
Я попробовал следующее:
В HTML:
<vaadin-upload id="upload" nodrop/>
В Java:
public class MyView extends PolymerTemplate<Model> {
private final MemoryBuffer buffer = new MemoryBuffer();
@Id("upload")
private final Upload upload = new Upload(buffer);
public MyView() {
upload.addSucceededListener(event -> {
System.out.println(event.getFileName());
System.out.println(buffer.getInputStream());
});
}
}
Когда я загружаю файл, я получаю следующее исключение:
[qtp162821120-20] ERROR com.vaadin.flow.server.DefaultErrorHandler -
com.vaadin.flow.server.UploadException: Upload failed
at com.vaadin.flow.server.communication.StreamReceiverHandler.streamToReceiver(StreamReceiverHandler.java:429)
Caused by: java.lang.IllegalStateException: Upload cannot be performed without a receiver set
at com.vaadin.flow.component.upload.Upload$DefaultStreamVariable.getOutputStream(Upload.java:581)
at com.vaadin.flow.server.communication.StreamReceiverHandler.streamToReceiver(StreamReceiverHandler.java:358)
2 ответа
Массовое редактирование: фактическое решение вашей проблемы состояло в том, что вы Upload
в вашем Java-классе, когда вы должны позволить Vaadin сделать это (из-за полимерного шаблона) и ссылаться на этот компонент загрузки, используя идентификатор как в html-шаблоне (<vaadin-upload id="upload" nodrop/>
), а также в коде Java (@Id("upload") private Upload upload;
). Теперь вы можете установить получатель загрузки в классе Java, используя upload.setReceiver(buffer);
,
public class MyView implements PolymerTemplate<Model> {
@Id("upload") // com.vaadin.flow.component.polymertemplate
private Upload upload; // NO INSTANTIATION!
private private final MemoryBuffer buffer = new MemoryBuffer();
public MyView (){
upload.setReceiver(buffer);
upload.addSucceededListener(event -> {
System.out.println(event.getFileName());
System.out.println(buffer.getInputStream());
});
}
}
Мой первоначальный ответ заключался в использовании ненужного альтернативного подхода, который не был связан с вашей проблемой (сначала я так думал), но помог найти реальное решение.
Лучшее решение немного зависит от вашего контекста, в основном, как ваш бэкэнд принимает данные? Принимает ли он входной поток, где он может читать данные, предоставляет ли он выходной поток, куда его записать, или есть простой байт [], где можно буферизовать содержимое.
Если вы используете Binder в своей форме, вы можете использовать ByteArrayUploadField из надстройки Viritin, которая напрямую привязывается к типу byte[], который вы, вероятно, имеете в своем доменном объекте.
Недавно я написал статью, которая объясняет функциональность компонента Vaadin Upload. Проверьте это для более подробной информации.