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