How to use Streamed Content with p:fileDownload to Download Non class path File
jsf, primefaces
Solution
The `NotSerializableException` is thrown because the view scope is represented by the JSF view state which can in turn be serialized to HTTP session in case of server side state saving or a HTML hidden input field in case of client side state saving. The `FileInputStream` can in no way be represented in a serialized form.
If you absolutely need to keep the bean view scoped, then you should not be declaring `StreamedContent` as an instance variable, but instead recreate it in the getter method. True, doing business logic in a getter method is usually frowned upon, but the `StreamedContent` is a rather special case. In the action method, you should then only prepare serializable variables which are later to be used during `DefaultStreamedContent` construction.
@ManagedBean
@ViewScoped
public class DownloadBean implements Serializable {
private String path;
private String contentType;
public void downloadAction() {
path = "C:/temp.txt";
contentType = FacesContext.getCurrentInstance().getExternalContext().getMimeType(path);
}
public StreamedContent getdFile() throws IOException {
return new DefaultStreamedContent(new FileInputStream(path), contentType);
}
}
(note that I also fixed your way to get the content type; you have this way much more freedom to configure mime types via `<mime-mapping>` entries in `web.xml`)
The `<p:graphicImage>` has by the way exactly the same problem with `StreamedContent`. See also among others Display dynamic image from database with p:graphicImage and StreamedContent.
Problem
I'm using Primefaces p:fileDownload to download a file which is not in class path. So I'm passing FileInputStream as parameter to DefaultStreamedContent. Every thing works fine when my bean is kept at @SessionScoped..., But java.io.NotSerializableException: java.io.FileInputStream is thrown when I keep my bean in @Viewscoped. My Code: DownloadBean.java ``` @ManagedBean @ViewScoped public class DownloadBean implements Serializable { private StreamedContent dFile; public StreamedContent getdFile() { return dFile; } public void setdFile(StreamedContent dFile) { this.dFile = dFile; } /** * This Method will be called when download link is clicked */ public void downloadAction() { File tempFile = new File("C:/temp.txt"); try { dFile = new DefaultStreamedContent(new FileInputStream(tempFile), new MimetypesFileTypeMap().getContentType(tempFile)); } catch (FileNotFoundException e) { e.printStackTrace(); } } } ``` index.xhtml ``` <h:form> <h:commandLink action="#{downloadBean.downloadAction}"> Download <p:fileDownload value="#{downloadBean.dFile}"/> </h:commandLink> </h:form> ``` Isn't there any method to make it work?