Important Notice - Forums is archived
To simplify things and help our users to be more productive, we have archived the current forum and focus our efforts on helping developers on Stack Overflow. You can post new questions on Stack Overflow or join our Discord channel.

Vaadin lets you build secure, UX-first PWAs entirely in Java.
Free ebook & tutorial.
Using DownloadStream - How to
I need to download a file directly on the client without any filechooser.
I found the class DownloadStream and I thought it was my solution, however I don't understand how to use it.
I tried with
String logFileName = "Import_"+nomeMatrice+".log";
byte[] cnt = new String("La vispa teresa avea tra l'erbetta").getBytes();
DownloadStream ds = new DownloadStream(new ByteArrayInputStream(cnt),"log",logFileName);
but nothing happened.
Could someone provide a snippet to use that class or duggest a different approach?
Tks
If by "filechooser" you mean the dialog that the browser shows when the user clicks a "downloadable" resource, then you cannot avoid it. This is not because of Vaadin but because of browsers. In any case, I found this example about how to download a file from Vaadin applications: http://www.programcreek.com/java-api-examples/index.php?api=com.vaadin.server.FileDownloader
Tks for Your help.
I already used FileDownloader in different situations but this is not my situation now.
The user shouldn't chose the file because there's no file : I've a byte stream I need to download.
I think DownloadStream is the correct answer but I didn't understand how to use it.
Tks
Sorry, I'm not sure if I understand conrrectly. Can you elaborate a bit on your requirement?
Sure.
In my code, when the user press a button, the code produces a stream of data I need to download as a file to the client.
I don't have a physical file to download.
I can, obviously, write a file on the server, if usefull, and the download it.
Tks
Ok, got it. You can do something like this:
Button button = new Button("Download the file");
// first, implement a StreamSource:
StreamSource source = () -> new ByteArrayInputStream("La vispa teresa avea tra l'erbetta".getBytes());
// second, create a StreamResource and pass the previous StreamResource:
StreamResource resource = new StreamResource(source, "file.txt");
// extend a component
FileDownloader downloader = new FileDownloader(resource);
downloader.extend(button);
Tried but I found a different problem.
The button I need to create is into a popup Window.
Using a FileDownloader extension into a popup goes into NPE.
Any suggestion ?
Tks
If you can you share the relevant parts of your code and the stack trace I could have a look.
The proble is a little more complex as I tought.
I've a small popup containing a file chooser, the file chooser (Upload class) when a file is choosen and I press the execute button the content of the file is elaborated and the log stream should be redirected to the browser.
Here the code
package axioma.web.configuratore.ui.dialogs;
import java.io.*;
import com.vaadin.server.*;
import com.vaadin.server.StreamResource.StreamSource;
import com.vaadin.ui.*;
import com.vaadin.ui.Button.ClickEvent;
import axioma.rubik.csv.MatriciCsvImporter;
import axioma.web.configuratore.model.domain.TipiMatrici;
import axioma.web.template.ui.components.*;
import axioma.web.template.ui.dialogs.YesNoDialog;
import axioma.web.template.ui.layouts.HorizontalCaptionLayout;
import axioma.web.template.ui.messages.TemplateMessages;
public class MatrixImportDialog extends YesNoDialog {
private static final long serialVersionUID = 1L;
private DocumentFileReceiverField fileReceiver;
private TipiMatrici tipiMatrice;
public MatrixImportDialog(TipiMatrici xpMatrice) {
super(TemplateMessages.CONFIRM_IMPORT.getText(),TemplateMessages.CONFIRM_IMPORT.getMessageCode(), null ,null, new String[]{});
tipiMatrice = xpMatrice;
}
@Override
public void createYesButton() {
createYesButton(TemplateMessages.BUTTON_UPLOAD.getText(),TemplateMessages.BUTTON_UPLOAD.getMessageCode());
DocumentDownloader downloader = new DocumentDownloader(null,"Import.csv") {
private static final long serialVersionUID = 1L;
@Override
protected Resource buildResource() {
System.out.println("Fatto ");
return rebuildResource();
}
};
downloader.extend(btnYes);
}
private StreamResource rebuildResource() {
byte[] logData = importa();
// System.out.println(logData);
byte[] logData2 = "ProvaMicrofono;".getBytes();
StreamSource source = () -> new ByteArrayInputStream(logData2);
StreamResource resource = new StreamResource(source, "Import.log");
return resource;
}
@Override
public void createNoButton() {
createNoButton(TemplateMessages.BUTTON_CLOSE.getText(),TemplateMessages.BUTTON_CLOSE.getMessageCode());
}
@Override
public Layout realBuildContent() {
VerticalLayout vl = new VerticalLayout();
vl.setSizeFull();
HorizontalCaptionLayout hl = new HorizontalCaptionLayout(1);
fileReceiver = new DocumentFileReceiverField("FileName");
fileReceiver.setCaption("File Name");
fileReceiver.setValue("");
fileReceiver.setWidth("100%");
hl.addComponent(fileReceiver);
hl.setWidth("100%");
vl.addComponent(hl);
return vl;
}
public String getFileName() {
return fileReceiver.getFileName();
}
public byte[] getContenuto() {
return fileReceiver.getContent();
}
public DocumentFileReceiverField getFileReceiver() {
return fileReceiver;
}
@Override
public void executeAction(ClickEvent xpEvent) {
}
public byte[] importa() {
try {
String nomeMatrice = tipiMatrice.getNome();
MatriciCsvImporter importer = new MatriciCsvImporter(nomeMatrice);
char[] contenuto = new String(getContenuto()).toCharArray();
Reader reader = new CharArrayReader(contenuto);
importer.setReader(reader);
String logFileName = "Import_"+nomeMatrice+".log";
CharArrayWriter cwriter = new CharArrayWriter();
Writer writer = new BufferedWriter(cwriter);
importer.setLogWriter(writer);
importer.setLogFileName(logFileName);
importer.doImport();
return new String(cwriter.toCharArray()).getBytes();
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
When I execute it and I don't open the file chooser it works, when I open the file chooser I get an error
java.lang.NullPointerException
at com.vaadin.server.FileDownloader.handleConnectorRequest(FileDownloader.java:134)
at axioma.web.template.ui.components.DocumentDownloader.handleConnectorRequest(DocumentDownloader.java:24)
at com.vaadin.server.ConnectorResourceHandler.handleRequest(ConnectorResourceHandler.java:90)
at com.vaadin.server.VaadinService.handleRequest(VaadinService.java:1409)
at com.vaadin.server.VaadinServlet.service(VaadinServlet.java:364)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:522)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1095)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:672)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
Going deeper it seems the UI is not accessible and/or the Session are not accessible from the FileDownloader.
Tks
Unfortunately what I described in my previous post is not true.
I get the same error also if I don't open the filechooser.
Here the relevant code
package axioma.web.configuratore.ui.dialogs;
import java.io.*;
import com.vaadin.server.*;
import com.vaadin.server.StreamResource.StreamSource;
import com.vaadin.ui.*;
import com.vaadin.ui.Button.ClickEvent;
import axioma.rubik.csv.MatriciCsvExporter;
import axioma.web.configuratore.model.domain.TipiMatrici;
import axioma.web.pax.ui.components.impl.StringField;
import axioma.web.template.ui.components.DocumentDownloader;
import axioma.web.template.ui.dialogs.*;
import axioma.web.template.ui.layouts.HorizontalCaptionLayout;
import axioma.web.template.ui.messages.TemplateMessages;
public class MatrixExportDialog extends YesNoDialog {
private static final long serialVersionUID = 1L;
private StringField fileName;
private String nomeMatrice;
private DocumentDownloader downloader;
public MatrixExportDialog(TipiMatrici xpMatrice) {
super(TemplateMessages.CONFIRM_EXPORT.getText(),TemplateMessages.CONFIRM_EXPORT.getMessageCode(), null ,null, new String[]{});
nomeMatrice = xpMatrice.getNome();
String defaultFileName = "Export_"+nomeMatrice+".csv";
fileName.setValue(defaultFileName);
}
@Override
public void createYesButton() {
createYesButton(TemplateMessages.BUTTON_DOWNLOAD.getText(),TemplateMessages.BUTTON_DOWNLOAD.getMessageCode());
addDownloader();
}
protected void addDownloader() {
downloader = new DocumentDownloader(null,"Export.csv") {
private static final long serialVersionUID = 1L;
@Override
protected Resource buildResource() {
return internalBuildResource();
}
};
downloader.extend(btnYes);
}
@Override
public void createNoButton() {
createNoButton(TemplateMessages.BUTTON_CLOSE.getText(),TemplateMessages.BUTTON_CLOSE.getMessageCode());
}
@Override
public Layout realBuildContent() {
VerticalLayout vl = new VerticalLayout();
vl.setSizeFull();
HorizontalCaptionLayout hl = new HorizontalCaptionLayout(1);
fileName = new StringField("FileName");
fileName.setValue("");
fileName.setWidth("100%");
hl.addComponent(fileName);
hl.setWidth("100%");
vl.addComponent(hl);
return vl;
}
public String getFileName() {
return fileName.getValue();
}
private Resource internalBuildResource() {
String name = getFileName();
char[] risultato = esporta();
byte[] dati = new String(risultato).getBytes();
System.out.println(dati);
byte[] dati2 = "Prova prova prova".getBytes();
StreamSource source = () -> new ByteArrayInputStream(dati2);
StreamResource resource = new StreamResource(source, name);
return resource;
}
private char[] esporta() {
try {
MatriciCsvExporter exporter = new MatriciCsvExporter(nomeMatrice);
CharArrayWriter stream = new CharArrayWriter();
Writer out = new BufferedWriter(stream);
exporter.setWriter(out);
exporter.export();
return stream.toCharArray();
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
@Override
public void executeAction(ClickEvent xpEvent) {}
}
Hi Tullio,
I've just tried FileDownloader in combination with popup window and I got no errors with vaadin 7.6.8.
Maybe some issue with YesNoDialog or DocumentDownloader classes? Can you post the code?