JSF PrimeFaces FileDownload问题

时间:2011-06-01 14:53:37

标签: jsf download primefaces

我正在使用PrimeFaces进行新项目,这是一组非常令人印象深刻的组件。 无论如何,我有使用filedownload组件的“真实世界”的问题。 在我的页面中,我有一个显示与特定文档相关的附件的datalist,我想提供一个链接,直接在datalist项目中下载该文件。 这是我的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>

和相对java bean(请求作用域):

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;
}

所以,有几个问题:

  1. 我是否正在尝试以这种方式传递所选附件?否则,我如何传递一个参数来告诉已经点击附件的bean?
  2. 为什么我第一次点击命令链接时,什么都没发生?它与服务器进行往返,但没有任何反应。第二次,它给了我一个例外。
  3. 为什么永远不会调用documentBean.selectAttach而且永远不会设置documentBean.selectedAttach属性(第二次都没有)?
  4. 感谢任何人的提示

2 个答案:

答案 0 :(得分:2)

在这个问题中回答了如何从数据表中获取行对象:

这基本上回答了所有三个问题。

对于第二次单击中的异常,这可能是因为在catch方法中抛出异常时,您没有从getDownloadFile()块返回。当rawFile仍为null时,您将继续保留代码流的剩余部分。也相应地修复它。在return null或其他内容的末尾添加catch。更好的是,您应该在问题中发布整个堆栈跟踪,因为您似乎无法理解它。它基本上已经包含了答案:)

答案 1 :(得分:0)

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;
}