Primefaces 文件下载仅在我使用默认构造函数时有效
Primefaces file download only works when I use the default constructor
我使用 HttpURLConnection 下载文件,然后我想为用户提供下载该文件的选项。我使用这个 primefaces 示例 http://www.primefaces.org/showcase/ui/file/download.xhtml。
我的问题是,如果我通过示例中提到的默认构造函数下载硬编码文件,一切正常。但是如果我将文件名传递给接受参数的构造函数,我会得到一个空指针。
这是带有两个构造函数的代码(只有带有硬编码文件的默认构造函数有效)
@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>
您不得在带有注释 @ManagedBean
的 class 中创建第二个构造函数来初始化文件名变量。
您可以使用 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>
或
<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>
在您的控制器中编写 actionEvent 并管理您的下载。
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);
}
你可以试试这个
@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}"/>
我使用 HttpURLConnection 下载文件,然后我想为用户提供下载该文件的选项。我使用这个 primefaces 示例 http://www.primefaces.org/showcase/ui/file/download.xhtml。
我的问题是,如果我通过示例中提到的默认构造函数下载硬编码文件,一切正常。但是如果我将文件名传递给接受参数的构造函数,我会得到一个空指针。
这是带有两个构造函数的代码(只有带有硬编码文件的默认构造函数有效)
@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>
您不得在带有注释 @ManagedBean
的 class 中创建第二个构造函数来初始化文件名变量。
您可以使用 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>
或
<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>
在您的控制器中编写 actionEvent 并管理您的下载。
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);
}
你可以试试这个
@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}"/>