【问题标题】:JSF PrimeFaces FileDownload problemJSF PrimeFaces FileDownload 问题
【发布时间】:2011-06-01 14:53:36
【问题描述】:

我正在将 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 属性(第二次都没有)?

感谢任何人的任何提示

【问题讨论】:

    标签: jsf download primefaces


    【解决方案1】:

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

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

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

    【讨论】:

    • 对不起,我不明白我做错了什么。我从您的博客文章开始构建该页面,但有些事情没有按预期工作,我不明白为什么。未调用 documentBean.selectAttach 操作。 documentBean.setSelectedAttach 也没有绑定到 setPropertyActionListener。只调用了 documentBean.getDownloadFile,并且返回 null,它会引发异常。我不明白这种行为的原因....此外,当我第一次单击 che 图像时,确实会发生往返,但没有调用任何操作方法或设置器:(
    • 我也做了一些实验,如果我删除 primefaces 文件下载标签,一切似乎都按预期工作:显然没有下载附件 :) 但所有设置器、获取器和操作都按预期调用,即使是我第一次点击图片。在我看来,primefaces 文件下载组件存在问题......
    • @themarcuz:好吧,在你的 catch 块中的最后一条指令之后,你继续处理 rawFile 很可能是空的。以前回来。或者更好的是,不要捕获异常(太宽),并为任何未捕获的内容提供适当的错误页面。
    【解决方案2】:

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

    【讨论】:

    • OP 已经在使用&lt;p:fileDownload&gt;。他只是在 getter 中而不是在 action 方法中做StreamedContent 创建工作。
    猜你喜欢
    • 2012-11-08
    • 2012-02-28
    • 1970-01-01
    • 1970-01-01
    • 2014-06-11
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    相关资源
    最近更新 更多