0

I have a JSF 2.2 xhtml page with a button within a form tag as follows - which enables the download of a file.

<h:form>
   <p:commandButton onclick="PrimeFaces.monitorDownload(start, stop);"
       value="#{filename}"
       id="download">
       <p:fileDownload 
       value = "#{downloadController.downloader(downloadController.file,
       reviewTableController.exam.id, filename)}" />
   </p:commandButton>
   <h:message for="download"/>
</h:form>

DownloadController (relevant parts thereof):

@Named
@ViewScoped
public class DownloadController implements Serializable {
    // other stuff    
    public StreamedContent downloader(StreamedContent file, int id, String filename) { 
    String resourcef = "/resources/default/files/"+filename;
    InputStream stream = FacesContext.getCurrentInstance().getExternalContext().getResourceAsStream(resourcef);
    file = new DefaultStreamedContent(stream, "application/pdf", filename);
    return file;
}

public StreamedContent getFile() throws IOException  {
    if (file == null) {
        System.out.println("File has not been placed in resources");
    } 
    if (file != null) {
            file.getStream().reset();   
    }
    return file;
} 
// getters and setters ...
}

So a user can download a file, if the correctly named file has been placed in the correct location. However there is a possibility that a file with the given filename is not present in the location from which it should be downloaded.

Currently in that case I get an error (500):

[2016-07-26T08:29:44.078+1000] [glassfish 4.1] [WARNING] [] 
[javax.enterprise.web] [tid: _ThreadID=108 _ThreadName = http-listener-1(1)]    
[timeMillis: 1469485784078] [levelValue: 900] [[
StandardWrapperValve[Faces Servlet]: Servlet.service() for servlet Faces Servlet threw exception
java.lang.NullPointerException
at org.primefaces.component.filedownload.FileDownloadActionListener.processAction(FileDownloadActionListener.java:77)
at javax.faces.event.ActionEvent.processListener(ActionEvent.java:88)
at javax.faces.component.UIComponentBase.broadcast(UIComponentBase.java:813)
at javax.faces.component.UICommand.broadcast(UICommand.java:300)
at com.sun.faces.facelets.component.UIRepeat.broadcast(UIRepeat.java:1045)
at javax.faces.component.UIViewRoot.broadcastEvents(UIViewRoot.java:790)
at javax.faces.component.UIViewRoot.processApplication(UIViewRoot.java:1282)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:81)
// etc

Obviously the error occurs because getFile() still has to return a file even if it's null

Rather than that, I'd like a message to occur on the xhtml page. It doesn't have to be a FacesMessage, a simple h:message or p:message such as "File has not been placed in resources" will do.

I can't figure out how to connect the exception event in DownloadController to an h:message in the xhtml page. Or rather, if there is a way of avoiding the exception; still registering or noting that file is null, and in that case serving an h:message -- or alternatively returning the file if the file exists.

Any assistance or comment appreciated. Thanks

anvw
  • 149
  • 3
  • 15
  • Have you tried something like a `try`/`catch` in our downloader method? Along with a `FacesContext.getCurrentInstance().addMessage(...)`? – Evan Knowles Jul 26 '16 at 11:39
  • in brief -- yes. I'll keep on cobbling away at it ... – anvw Jul 26 '16 at 12:33
  • Using that is the general strategy - you could also look at implenting a custom exception handler, but you may as well handle it where it occurs. – Evan Knowles Jul 26 '16 at 16:08
  • Maybe try the two-step solution like in http://stackoverflow.com/questions/25687625/how-to-stream-a-file-download-and-display-a-jsf-faces-message – Kukeltje Jul 26 '16 at 19:16

0 Answers0