JSF PrimeFaces 文件下载问题

发布于 2024-11-11 04:20:40 字数 2580 浏览 2 评论 0原文

我正在将 PrimeFaces 用于一个新项目,它是一组令人印象深刻的组件。 不管怎样,我对文件下载组件的“现实世界”使用有疑问。 在我的页面中,我有一个数据列表,显示与特定文档相关的附件,我想提供一个链接来直接下载数据列表项中的该文件。 这是我的 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 属性(第二次也没有)?

感谢任何人的任何提示

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:

  1. 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?
  2. 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.
  3. Why documentBean.selectAttach is never called and the documentBean.selectedAttach property is never set (neither the second time)?

Thanks to anyone for any hint

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

千纸鹤 2024-11-18 04:20:40

如何从数据表中获取行对象在这个问题中得到解答:

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

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

How to get the row object from the datatable is answered in this question:

This answers basically all the three questions.

As to the exception in the second click, that's likely because you didn't return from the catch block when an exception is been thrown in your getDownloadFile() method. You're continuing the remnant of the code flow while the rawFile is still null. Fix it accordingly as well. Add a return null to the end of catch or something. Better yet, you should be posting the entire stacktrace in the question as you don't seem to be able to understand it. It basically already contains the answer :)

阳光下的泡沫是彩色的 2024-11-18 04:20:40

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

Primefaces has its own dedicated servlet for file download and upload components that handle all of this asynchronously.

Try doing something like what I have in my code

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

And in the managed 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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文