【问题标题】:PrimeFaces fileDownload does not workPrimeFaces 文件下载不起作用
【发布时间】:2011-06-14 09:49:01
【问题描述】:

我无法让 primeFaces <p:filedownload 工作。虽然我使用自定义下载 bean 成功下载了文件。似乎问题与primefaces文件下载ActionListener有关,但我不知道如何。有人有线索吗?谢谢。

这是我的豆子:

@ManagedBean(name="fileDownloadBean")
@SessionScoped
public class FileDownloadBean implements Serializable {

    private StreamedContent file;

    public StreamedContent getFile() {
        return file;
    }

    public void setFile(StreamedContent file) {
        this.file = file;
    }

    /** Creates a new instance of FileDownloadBean */
    public FileDownloadBean() {
        InputStream stream = this.getClass().getResourceAsStream("sessionlog.csv");
        file = new DefaultStreamedContent(stream, "application/csv", "sessionlog.csv");

    }
}

这是我的视图代码:

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:p="http://primefaces.prime.com.tr/ui" 
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:o="http://openfaces.org/"
                template="./../template.xhtml">

    <ui:define name="title">
        #{bundle.Log}
    </ui:define>

    <ui:define name="body">
        <h:form>
            <p:separator style="height: 10px;margin-bottom: 10px;margin-top: 0px;"/>
            <p:commandButton value="#{bundle.Log}" image="ui-icon ui-icon-link" ajax="false" disabled="false">
                <p:fileDownload value="#{fileDownloadBean.file}" />
            </p:commandButton>
</ui:composition>

我收到 500 错误:NullPointerException:

HTTP Status 500 -

type Exception report

message

descriptionThe server encountered an internal error () that prevented it from fulfilling this request.

exception

javax.servlet.ServletException
root cause

java.lang.NullPointerException
note The full stack traces of the exception and its root causes are available in the GlassFish Server Open Source Edition 3.1 logs.

GlassFish Server Open Source Edition 3.1

日志:

WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
    at org.primefaces.component.filedownload.FileDownloadActionListener.processAction(FileDownloadActionListener.java:59)
    at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
    at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:769)
    at javax.faces.component.UICommand.broadcast(UICommand.java:300)
    at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:794)
    at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1259)
    at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)
    at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1534)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:281)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
    at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:326)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:227)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:170)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:822)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:719)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1013)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:662)

【问题讨论】:

    标签: jsf download primefaces java-ee-5


    【解决方案1】:
    InputStream stream = this.getClass().getResourceAsStream("sessionlog.csv");
    

    您找到 CSV 文件的方式预计它与当前类 FileDownloadBean 位于相同的包中。

    如果它实际上位于包根目录中,那么您应该使用:

    InputStream stream = this.getClass().getResourceAsStream("/sessionlog.csv");
    

    或者如果它实际上位于不同的包中,例如com.example,那么您应该使用:

    InputStream stream = this.getClass().getResourceAsStream("/com/example/sessionlog.csv");
    

    或者,如果它实际上位于公共 web 内容的根目录中(/WEB-INF 文件夹也在所有其他 web 文件中),那么您应该使用:

    InputStream stream = externalContext.getResourceAsStream("/sessionlog.csv");
    

    (顺便说一下,它也适用于 WAR 类而不是 this.getClass()

    【讨论】:

    • 没错,终于是路径问题了。个人疏忽大意。我在基于 Debian 的 Linux 下,所以有时路径可能会变得很棘手,这就是我 simlpy 使用“文件名”的原因。再次感谢您的宝贵说明。
    • 使用ClassLoader#getResourceAsStream(),您应该考虑相对于类路径根(即包根)。使用ExternalContext#getResourceAsStream(),您应该考虑相对于 webapp 根目录(即 WebContent 文件夹)。当您想直接从本地磁盘文件系统中获取它们时,您应该使用带有绝对磁盘文件系统路径的FileInputStream
    • 我的问题是,当通过 HttpsessionListener 的 sessionCreated() 方法创建文件时, File file = new File("sessionlog.csv");它存储在 /home/mediterran/glassfish/glassfish/domains/domain1/sessionlog.csv 所以实际上,我不知道如何指示路径,以便文件应该写在与 /WEB- 相同的根目录中信息
    • 你真的应该避免在 web 应用程序中使用带有相对路径的 File。相对路径取决于服务器的启动方式。另请参阅我对以下问题的回答:stackoverflow.com/questions/2308188/…stackoverflow.com/questions/6059453/…
    【解决方案2】:

    我正在修改我的 InputStream 代码

    InputStream stream = this.getClass().getResourceAsStream("sessionlog.csv");
    

    改变

    InputStream stream = new FileInputStream(new File("URL"))
    

    这是解决方案。

    【讨论】:

      【解决方案3】:

      您确定已成功将 CSV 文件作为资源从类加载吗?看起来 InputStream 可能为空。

      【讨论】:

      • @balusC 确实,由于文件下载器找不到文件然后返回空值而引发错误。我将文件的位置更改为同一个类包,现在可以正常工作了。
      【解决方案4】:

      我的fileuplaad.xhtml如下图

        <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:f="http://java.sun.com/jsf/core"
          xmlns:ui="http://java.sun.com/jsf/facelets"
          xmlns:p="http://primefaces.org/ui">
      
      
          <h:form id="downloadFileForm">
                  <p:commandButton id="downloadLink" value="Download"                                                                             ajax="false"
                                                      onclick="PrimeFaces.monitorDownload(start, stop)"
                                                      icon="ui-icon-arrowthichk-s">
                                                      <p:fileDownload value="#{fileDownloadController.file}" />
                                                  </p:commandButton>
      
      
              </h:form>
          </html>
      
      Here is my bean:
      @ManagedBean(name="fileDownloadController")
      public class FileDownloadController implements Serializable {
      
      
          private static final long serialVersionUID = 1L;
      
          private StreamedContent file;  
      
      
          public FileDownloadController() {          
              InputStream stream = ((ServletContext)FacesContext.getCurrentInstance().getExternalContext().getContext()).getResourceAsStream("/download/FileName.csv");  
              file = new DefaultStreamedContent(stream, "download/csv", "FileName.csv");  
          }  
      
          public StreamedContent getFile() {  
              return file;  
          }    
      }
      

      【讨论】:

        猜你喜欢
        • 2013-04-12
        • 2017-01-17
        • 2013-02-05
        • 1970-01-01
        • 2011-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多