我正在为一个新项目使用PrimeFaces,它是一组令人印象深刻的组件。无论如何,我对"现实世界"中使用filedownload组件有问题。在我的页面中,我有一个数据列表,显示了与特定文档相关的附件,我想在数据列表项中提供一个直接下载该文件的链接。这是我的xhtml代码:
<p:dataList id="ListaAllegati" value="#{documentBean.documento.allegati}" type="definition" var="attach" style="border: none" ">
<f:facet name="description">
<h:outputText value="#{attach.name}" />
<p:commandLink ajax="false" title="Download" action="#{documentBean.selectAttach}>
<h:graphicImage style="margin-left: 10px; border: none" value="./images/article.png" height="24" width="24" ></h:graphicImage>
<p:fileDownload value="#{documentBean.downloadFile}"/>
<f:setPropertyActionListener target="#{documentBean.selectedAttach}" value="#{attach}" />
</p:commandLink>
</f:facet>
</p:dataList>
以及相对的javabean(请求范围):
private StreamedContent downloadFile;
public StreamedContent getDownloadFile() {
log.info("getter dell'allegato invocato");
InputStream stream = null;
byte[] rawFile = null;
if (selectedAttach == null) {
log.warn("Nessun allegato passato");
return null;
} else {
try {
log.info("Recupero del file " + selectedAttach.getGuid());
rawFile = attachManager.retrieveFile(selectedAttach.getGuid());
} catch (Exception e) {
String msg = "Errore durante il recupero del file";
log.error(msg, e);
FacesMessage fmsg = new FacesMessage(msg, "");
FacesContext.getCurrentInstance().addMessage(null, fmsg);
}
stream = new ByteArrayInputStream(rawFile);
DefaultStreamedContent file = new DefaultStreamedContent(stream,
selectedAttach.getMimeType(), selectedAttach.getName());
return file;
}
}
public void selectAttach() {
log.info("commandLink action invocata");
}
private Allegato selectedAttach;
public Allegato getSelectedAttach() {
return selectedAttach;
}
public void setSelectedAttach(Allegato selectedAttach) {
log.info("Allegato selezionato");
if (selectedAttach==null) log.warn("L'allegato passato è nullo");
this.selectedAttach = selectedAttach;
}
所以,有几个问题:
- 尝试以这种方式传递所选附件是否正确?否则,我如何传递一个参数来告诉bean附件被点击了
- 为什么我第一次点击命令链接时,什么都没发生?它与服务器进行了一次往返,但什么也没发生。第二次,它给了我一个例外
- 为什么从未调用documentBean.selectedAttach,也从未设置documentBean.sectedAttach属性(第二次也没有)
感谢任何人的任何提示
如何从数据表中获取行对象的答案如下:
- 如何将所选行传递给dataTable内的commandLink
这基本上回答了所有三个问题。
至于第二次单击中的异常,这可能是因为当在getDownloadFile()
方法中抛出异常时,您没有从catch
块返回。当rawFile
仍然是null
时,您正在继续代码流的剩余部分。也相应地进行修复。在catch
的末尾添加一个return null
之类的。更好的是,你应该发布问题中的整个堆栈,因为你似乎无法理解它。它基本上已经包含了答案:)
Primefaces有自己的专用servlet,用于异步处理所有这些的文件下载和上传组件。
试着做一些类似我在代码中所做的事情
<p:commandLink ajax="false" actionListener="#{managedBean.downloadAction(object)}">
<span class="ui-icon icoFolderGo" style="padding-right: 1.5em;" />
<p:fileDownload value="#{managedBean.downloadContentProperty}" />
</p:commandLink>
在托管bean中,
public void downloadAction(Object object) {
try {
InputStream stream = // get input stream from argument
this.setDownloadContentProperty(new DefaultStreamedContent(stream, "application/pdf", "filename.pdf");
} catch (Exception e) {
log.error(e);
}
}
public void setDownloadContentProperty(StreamedContent downloadContentProperty) {
this.downloadContentProperty = downloadContentProperty;
}
public StreamedContent getDownloadContentProperty() {
return downloadContentProperty;
}