2011-12-21 146 views
0

這是我xhtml-code下載文件

 <p:tree value="#{documentsController.root}" 
       var="node" selectionMode="single" 
       dynamic="true"> 

      <p:treeNode 
       expandedIcon="ui-icon-folder-open" 
       collapsedIcon="ui-icon-folder-collapsed"> 
       <h:outputText value="#{node}" /> 
      </p:treeNode> 

      <p:treeNode type="file" icon="ui-icon-document"> 
       <h:outputText value="#{node}"/> 
      </p:treeNode> 

      <p:ajax event="select" listener="#{documentsController.onNodeSelect}"/> 

     </p:tree> 

,這是支持bean

@ManagedBean 
@ViewScoped 
public class DocumentsController implements Serializable { 

    TreeNode root; 
    //TreeNode[] selectedNodes; 

    @PostConstruct 
    public void init() { 

     root = new DefaultTreeNode("SRC", null); 

     TreeNode node0 = new DefaultTreeNode("A", root); 
     TreeNode node1 = new DefaultTreeNode("B", root); 
     TreeNode node2 = new DefaultTreeNode("C", root); 

     TreeNode node3 = new DefaultTreeNode("file", "D", node0); 
     TreeNode node4 = new DefaultTreeNode("file", "E", node0); 
     TreeNode node5 = new DefaultTreeNode("file", "F", node0); 

     String p = "C:\\Users\\federico.martinez\\Desktop\\a.wmv"; 

     TreeNode node6 = new DefaultTreeNode("file", new File(p), node1); 
     TreeNode node7 = new DefaultTreeNode("file", "h", node1); 
     TreeNode node8 = new DefaultTreeNode("file", "i", node1); 

    } 

    public TreeNode getRoot() { 
     return root; 
    } 

    /* 
    public void setSelectedNodes(TreeNode[] selectedNodes){ 
    this.selectedNodes = selectedNodes; 
    } 

    public TreeNode[] getSelectedNodes(){ 
    return selectedNodes; 
    }*/ 
    public void onNodeSelect(NodeSelectEvent event) { 
     if (event.getTreeNode().getType().equals("file")) { 
      File file = new File(event.getTreeNode().getData().toString()); 
      FacesContext facesContext = FacesContext.getCurrentInstance(); 
      ExternalContext externalContext = facesContext.getExternalContext(); 

      externalContext.setResponseHeader("Content-Type", externalContext.getMimeType(file.getName())); 
      externalContext.setResponseHeader("Content-Length", String.valueOf(file.length())); 
      externalContext.setResponseHeader("Content-Disposition", "attachment;filename=\"" + file.getName() + "\""); 

      InputStream input = null; 
      OutputStream output = null; 

      try { 
       input = new FileInputStream(file); 
       output = externalContext.getResponseOutputStream(); 
       IOUtils.copy(input, output); 
      } catch (FileNotFoundException ex) { 
       System.out.println("FileNotFound: " + ex.getMessage()); 
      } catch (IOException ex) { 
       System.out.println("IO: " + ex.getMessage()); 
      } finally { 
       IOUtils.closeQuietly(output); 
       IOUtils.closeQuietly(input); 
      } 
      facesContext.responseComplete(); 
     } 
    } 
} 

但它不是下載文件,我用戰斧樹這種下載方法和它的工作,現在我想與PrimeFaces,但這不會下載該文件,並沒有錯誤!

任何意見可能是錯誤的?

在此先感謝!

UPDATE

我有這樣的修改,但不能讓它下載文件。

 <p:tree value="#{documentsController.root}" 
       var="node" selectionMode="single" 
       dynamic="true"> 

      <p:treeNode 
       expandedIcon="ui-icon-folder-open" 
       collapsedIcon="ui-icon-folder-collapsed"> 
       <h:outputText value="#{node}" /> 
      </p:treeNode> 

      <p:treeNode type="file" icon="ui-icon-document"> 
       <p:commandButton value="#{node}" ajax="false"> 
        <p:fileDownload value="#{documentsController.download(node)}" /> 
       </p:commandButton> 
      </p:treeNode> 

     </p:tree> 

和backbean是

public void download(String path) { 

    File f = new File(path); 
    FacesContext facesContext = FacesContext.getCurrentInstance(); 
    ExternalContext externalContext = facesContext.getExternalContext(); 

    InputStream is = ((ServletContext)externalContext.getContext()).getResourceAsStream(path); 

    file = new DefaultStreamedContent(is, externalContext.getMimeType(f.getName()), f.getName()); 

} 

public StreamedContent getFile(){ 
    return file; 
} 
+0

我現在沒有時間去測試它 - 但有可能是因爲其在「吃」您的請求下載的primefaces API中的AJAX調用。你應該看看,而不是使用actionlistener顯示下載文件的和'ajax =「false」'。這將創建一個鏈接(它可以提前動態更改),該鏈接將持續而不是觸發更新。我在桌子上遇到了類似的問題,並且很快就將其解決了。祝你好運。 – 2011-12-22 01:37:53

+0

非常感謝! 替換了ajax標籤?或者treeNode標籤(顯示文檔的標籤)? – BRabbit27 2011-12-22 05:21:10

回答

2

你的第一個問題是,你試圖通過一個Ajax請求下載一個文件。這不可能。 Ajax由JavaScript代碼執行和管理。 JavaScript已經由於安全限制而無法觸發另存爲對話。您需要改爲啓用一個完整的同步請求。如果內容配置設置爲attachment,原始頁面將保持不變。

所以,你至少需要一個<h:commandButton><p:commandButton ajax="false">

你,你當你試圖使用<p:fileDownload>了第二個問題是,value必須指向返回StreamedContent,不void的方法。您已將其綁定到void方法,因此不會返回任何內容。

因此,您需要將的值返回StreamedContent

你的第三個問題是,你得到的ServletContext#getResourceAsStream()的文件作爲類路徑資源(我相信你盲目地從PrimeFaces copypasted展示例子,這又是本身也蠻可憐的,它可能只是使用了ExternalContext#getResourceAsStream()代替無需要從JSF的引擎蓋下抓取ServletContext,但這不在),而不是像原始代碼中的FileInputStream

所以,要麼這些解決方案必須幫助:

<p:treeNode type="file" icon="ui-icon-document"> 
    <p:commandButton value="#{node}" ajax="false"> 
     <p:fileDownload value="#{documentsController.download(node)}" /> 
    </p:commandButton> 
</p:treeNode> 

public StreamedContent download(String path) { 
    File file = new File(path); 
    InputStream input = new FileInputStream(file); 
    ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext(); 
    return new DefaultStreamedContent(input, externalContext.getMimeType(file.getName()), file.getName()); 
} 

<p:treeNode type="file" icon="ui-icon-document"> 
    <h:commandButton value="#{node}" action="#{documentsController.download(node)}" /> 
</p:treeNode> 

與原有onNodeSelect()方法與參數更改爲String path

+0

Puf ...以及我嘗試與你的(相同的確切代碼)和我的一些變化,但唯一發生的是頁面刷新(就像我將被重定向到其他地方),沒有文件被下載.. – BRabbit27 2011-12-22 19:13:44

+0

我以前見過''的一些奇怪問題(我以前從來沒有用過它,所以我不能詳細介紹)。改爲使用常規的''。 – BalusC 2011-12-22 19:21:09

+0

Balus在這裏的錢已經死了:有時組件內部的行爲「不穩定」。你可以嘗試顛倒它,所以而不是一個方法調用你只是有一個集合和每個元素是一個「可下載的」流式內容 - 它通常是我採取的方法,它的工作原理。仔細檢查以確保ajax =「false」 - 它會破壞它。 – 2011-12-22 20:45:11