I have a download action implemented on my Vaadin application but for some reason the downloaded file has the original file's full path as the file name.
Any idea?
You can see the code on this post.
Edit:
Here's the important part of the code:
package com.bluecubs.xinco.core.server.vaadin;
import com.bluecubs.xinco.core.server.XincoConfigSingletonServer;
import com.vaadin.Application;
import com.vaadin.terminal.DownloadStream;
import com.vaadin.terminal.FileResource;
import java.io.*;
import java.net.URLEncoder;
import java.util.UUID;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
/**
*
* @author Javier A. Ortiz Bultrón<[email protected]>
*/
public class FileDownloadResource extends FileResource {
private final String fileName;
private File download;
private File newFile;
public FileDownloadResource(File sourceFile, String fileName,
Application application) {
super(sourceFile, application);
this.fileName = fileName;
}
protected void cleanup() {
if (newFile != null && newFile.exists()) {
newFile.delete();
}
if (download != null && download.exists() && download.listFiles().length == 0) {
download.delete();
}
}
@Override
public DownloadStream getStream() {
try {
//Copy file to directory for downloading
InputStream in = new CheckedInputStream(new FileInputStream(getSourceFile()),
new CRC32());
download = new File(XincoConfigSingletonServer.getInstance().FileRepositoryPath
+ System.getProperty("file.separator") + UUID.randomUUID().toString());
newFile = new File(download.getAbsolutePath() + System.getProperty("file.separator") + fileName);
download.mkdirs();
OutputStream out = new FileOutputStream(newFile);
newFile.deleteOnExit();
download.deleteOnExit();
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
final DownloadStream ds = new DownloadStream(
new FileInputStream(newFile), getMIMEType(), fileName);
ds.setParameter("Content-Disposition", "attachment; filename="
+ URLEncoder.encode(fileName, "utf-8"));
ds.setCacheTime(getCacheTime());
return ds;
} catch (final FileNotFoundException ex) {
Logger.getLogger(FileDownloadResource.class.getName()).log(Level.SEVERE, null, ex);
return null;
} catch (IOException ex) {
Logger.getLogger(FileDownloadResource.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
}
I already debugged and verified that fileName only contains the file's name not the whole path.
The answer was actually a mix of houman001's answer and this post: https://vaadin.com/forum/-/message_boards/view_message/200534
I went away from the above approach to a simpler working one:
StreamSource ss = new StreamSource() {
byte[] bytes = //Get the file bytes here
InputStream is = new ByteArrayInputStream(bytes);
@Override
public InputStream getStream() {
return is;
}
};
StreamResource sr = new StreamResource(ss, <file name>, <Application Instance>);
getMainWindow().open(sr, "_blank");