PrimeFaces fileDownload does not work
Asked Answered
D

4

8

I can't get the primeFaces <p:filedownload work. While I succeed in downloading the file using a custom download bean. Seems like the issu is related to the primefaces file download ActionListener but I don't see how. Does anyone have a clue? Thanks.

Here is my bean:

@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");

    }
}

and here is my view code:

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

I get a 500 error: 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

LOG:

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)
Dysphemism answered 14/6, 2011 at 9:49 Comment(0)
M
12
InputStream stream = this.getClass().getResourceAsStream("sessionlog.csv");

The way as you have located the CSV file expects it to be in the same package as the current class, the FileDownloadBean.

If it is actually located in the package root, then you should rather be using:

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

Or if it is actually located in a different package, for example com.example, then you should rather be using:

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

Or if it is actually located in the root of the public webcontent (there where the /WEB-INF folder also is, among all other web files), then you should rather be using:

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

(which by the way also works fine for the WAR classes instead of this.getClass())

Marti answered 14/6, 2011 at 11:15 Comment(4)
Exactly, it is finally a path issue. Big personal inattention. I am under a Debian based Linux so paths might get tricky sometimes that is why I simlpy used "filename". Thank you again for the precious elucidation.Dysphemism
With ClassLoader#getResourceAsStream() you should be thinking relative to the classpath root (i.e. the package root). with ExternalContext#getResourceAsStream() you should be thinking relative to the webapp root (i.e. the WebContent folder). When you want to grab them from the local disk file system directly, then you should rather be using FileInputStream with an absolute disk file system path.Marti
my issue is that when the file is created through the sessionCreated() method of the HttpsessionListener , File file = new File("sessionlog.csv"); it is stored /home/mediterran/glassfish/glassfish/domains/domain1/sessionlog.csv So actually, I can't figure how to indicate a path so that the file should gets written somewhere like in the same root directory as /WEB-INFDysphemism
You should really avoid using File with a relative path in webapplications. The relative path is dependent on the way how the server is started. See also my answers on the following questions: #2308688 and #6059953Marti
H
3

I am modify my InputStream the code

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

change by

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

it was solution.

Hedley answered 20/12, 2011 at 15:42 Comment(0)
N
2

Are you sure that you are successfully loading the CSV file as a resource from the Class? It looks like the InputStream may be null.

Nicely answered 14/6, 2011 at 11:5 Comment(1)
@balusC Indeed, the error was thrown because the filedownloader could not locate the file and then returned a null value. I changed the location of the file to the same class package and it is working fine now.Dysphemism
L
0

My fileuplaad.xhtml is as shown below

  <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;  
    }    
}
Liquidity answered 11/1, 2014 at 6:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.