Vaadin:下载的文件有整个路径作为文件名

时间:2011-11-17 14:59:48

标签: download filenames vaadin

我在我的Vaadin应用程序上实现了下载操作,但出于某种原因,下载的文件将原始文件的完整路径作为文件名。

有什么想法吗?

您可以看到代码on this post

修改

以下是代码的重要部分:

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<javier.ortiz.78@gmail.com>
 */
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;
        }
    }
}

我已经调试并验证了fileName只包含文件名而不是整个路径。

3 个答案:

答案 0 :(得分:4)

答案实际上是houman001的回答和这篇文章的混合:https://vaadin.com/forum/-/message_boards/view_message/200534

我从上述方法转向更简单的工作方式:

         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");

答案 1 :(得分:1)

这是我的代码可以正常工作(从数据库中将blob作为文件下载),但它在你的情况下使用Servlet和OutputStream而不是DownloadStream:

public class TextFileServlet extends HttpServlet
{
    public static final String PARAM_BLOB_ID = "id";

    private final Logger logger = LoggerFactory.getLogger(TextFileServlet.class);

    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException
    {
        Principal userPrincipal = req.getUserPrincipal();
        PersistenceManager pm = PMFHolder.get().getPersistenceManager();
        Long id = Long.parseLong(req.getParameter(PARAM_BLOB_ID));
        MyFile myfile = pm.getObjectById(MyFile.class, id);

        if (!userPrincipal.getName().equals(myfile.getUserName()))
        {
            logger.info("TextFileServlet.doGet - current user: " + userPrincipal + " file owner: " + myfile.getUserName());
            return;
        }

        res.setContentType("application/octet-stream");
        res.setHeader("Content-Disposition", "attachment;filename=\"" + myfile.getName() + "\"");
        res.getOutputStream().write(myfile.getFile().getBytes());
    }
}

我希望它可以帮到你。

答案 2 :(得分:0)

StreamResource myResource = createResource(attachmentName);
System.out.println(myResource.getFilename());
if(attachmentName.contains("/"))
   attachmentName = attachmentName.substring(attachmentName.lastIndexOf("/"));
if(attachmentName.contains("\\"))
   attachmentName = attachmentName.substring(attachmentName.lastIndexOf("\\"));
myResource.setFilename(attachmentName);
FileDownloader fileDownloader = new FileDownloader(myResource);
fileDownloader.extend(downloadButton);