2011-11-17 56 views
2

我在我的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<[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; 
     } 
    } 
} 

我已經調試和驗證該文件名只包含文件的名稱不整的路徑。

+0

將是很好,有一些代碼直接在這裏查看... –

+0

在此處添加代碼,只是爲了避免重複。 – javydreamercsw

回答

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

你能回答你的問題嗎? –

+0

完成後,我無法做到這一點,我不得不等待一段時間(消息彈出) – javydreamercsw

+0

@javydreamercsw非常感謝。 – Hulk

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()); 
    } 
} 

我希望它可以幫助你。

+0

它會但我目前的代碼(目前發佈)這樣做。我正在遷移到Vaadin。 – javydreamercsw

+0

您的回答讓我記住我的網絡服務仍然可以讓我找到答案。 – javydreamercsw

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); 
相關問題