I'm using PrimeFaces for a new project and it's quite an impressive set of components. Anyway, I have problem with "real world" use of filedownload component. In my page I have a datalist that shows the attachments related to a particular document, and I want provide a link to directly download that file inside the datalist item. Here's my xhtml code:
<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>
and the relative java bean (request scoped):
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;
}
So, couple of question:
- Am I doing the right thing trying to pass the selected attachment that way? Otherwise, how can I pass a parameter to tell the bean wich attachment has been clicked?
- Why the first time I click the command link, nothing happen? It make a roundtrip with server, but nothing happens. Second time, it gives me an exception.
- Why documentBean.selectAttach is never called and the documentBean.selectedAttach property is never set (neither the second time)?
Thanks to anyone for any hint