2016-05-21 20 views
-1

我使用HttpURLConnection下載文件,然後我想給用戶下載該文件的選項。我使用這個primefaces示例http://www.primefaces.org/showcase/ui/file/download.xhtmlPrimefaces文件下載只適用於我使用默認構造函數

我的問題是,如果我通過默認的構造函數下載硬編碼文件,就像它在示例中提到的那樣,一切正常。但如果我將文件名傳遞給接受param的構造函數,我會得到一個空指針。

下面是這兩個構造函數的代碼(僅使用硬編碼的文件工作的默認構造函數)

@ManagedBean 

public class FileDownloadView { 

    private StreamedContent file; 
    private InputStream stream; 
    private String fileName; 

    public String getFileName() { 
     return fileName; 
    } 


    public FileDownloadView() { 
     InputStream stream = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/tmp/1kb.txt"); 
     file = new DefaultStreamedContent(stream, "text/plain", "text.txt"); 
     System.out.println("fileName......." + "test.txt"); 

    } 

    public FileDownloadView(String fileName) { 
     this.fileName = fileName; 

     InputStream stream = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/tmp/" + fileName); 
     this.fileName = fileName; 
     file = new DefaultStreamedContent(stream, "text/plain", fileName); 
     System.out.println("fileName......." + file.getName()); 

    } 

    public StreamedContent getFile() { 
     System.out.println("file "+file.getName()); 

     return file; 
    } 
} 

在這裏,我是多麼拉文件

 <p:commandButton value="Download" ajax="false" onclick="PrimeFaces.monitorDownload(start, stop);" icon="ui-icon-arrowthick-1-s"> 
       <p:fileDownload value="#{fileDownloadView.file}" /> 
      </p:commandButton> 

      <p:outputLabel value="#{fileDownloadView.fileName}"/> 
     </h:form> 
     <script type="text/javascript"> 
             function start() { 
              PF('statusDialog').show(); 
             } 

             function stop() { 
              PF('statusDialog').hide(); 
             } 
     </script> 
+1

誰去調用構造函數?不是JSF。 – EJP

回答

1

您可以使用f:attribute將文件名從您的UI傳遞到控制器並調用下載。

根據標籤的定義,它提供了一個選項,通過動作偵聽器將屬性值傳遞給組件或參數。

所以在你的情況下,你想傳遞文件名到控制器並相應地下載文件。

<p:commandButton value="Download" ajax="true" actionListener="#{fileDownloadView.prepareToDownload}" icon="ui-icon-arrowthick-1-s"> 
       <p:fileDownload value="#{fileDownloadView.file}" /> 
       <f:attribute name="fileName" value="#{fileDownloadView.fileName}" /> 
    </p:commandButton> 

OR

<h:commandLink id="downloadLink" 
    title="Download" 
    actionListener="#{fileDownloadView.prepareToDownload}"> 
    <p:graphicImage value="/resources/common/images/download.gif" 
     alt="Download" /> 
     <f:attribute name="fileName" value="#{fileDownloadView.fileName}" /> 
     <p:fileDownload value="#{fileDownloadView.file}" /> 
</h:commandLink> 

在你的控制器寫入動作事件和管理您的下載。

public void prepareToDownload(ActionEvent actionEvent){ 
     String fileName = (String)actionEvent.getComponent().getAttributes().get("fileName"); 
     InputStream stream = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/tmp/" + fileName); 
     file = new DefaultStreamedContent(stream, "text/plain", fileName); 
    } 
+0

我不明白這一行您能否提供更多的細節?我用我的控制器名稱更改了viewEDI。但不知道如何使用f:屬性 – Moe

+0

對不起。我有複製粘貼我在我的項目中使用的代碼。現在我已經更新了我的答案。你可以嘗試一樣的。 – Unknown

+0

感謝詳細的解釋,我發佈了另一個關於爲什麼按鈕不在Datatable內部觸發的問題。但如果它不在數據表中,它就可以工作。讓我知道你是否可以看看。再次感謝!!! – Moe

0

您不能創建類中的第二個構造函數,註釋@ManagedBean用於初始化文件名​​變量。

+0

那麼,我的問題的解決方案是什麼。如何完成我的任務?通過傳遞參數下載文件? – Moe

-1

你可以試試這個

@ManagedBean 
public class FileDownloadView { 

private StreamedContent file; 
private InputStream stream; 
private String fileName = "error"; 

public String getFileName() { 
    return fileName; 
} 
public void setFileName(String _filename) { 
    this.fileName = _fileName; 
} 
public FileDownloadView() { 

} 

的方法prepareToDownload允許管理文件下載。這樣我們就可以恢復文件名。

public void prepareToDownload(ActionEvent actionEvent){ 
    setFileName((String)actionEvent.getComponent().getAttributes().get("fileName")); 
    InputStream stream = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream("/tmp/" + fileName); 
    setFile(new DefaultStreamedContent(stream, "text/plain", fileName)); 
} 
public StreamedContent getFile() { 
    System.out.println("file "+file.getName()); 

    return file; 
} 
public void setFile(StreamedContent _file) { 
    this.file = _file; 

} 
} 
} 

,然後在XHTML文件:

<h:commandLink id="downloadLink" 
title="Download" 
actionListener="#{fileDownloadView.prepareToDownload}"> 
<p:graphicImage value="/resources/common/images/download.gif" 
    alt="Download" /> 
    <f:attribute name="fileName" value="#{fileDownloadView.fileName}" /> 
    <p:fileDownload value="#{fileDownloadView.file}" /> 
</h:commandLink> 
<h:outputText value="#{fileDownloadView.fileName}"/> 
+0

請添加一些解釋... – Kukeltje