I have an issue related to Primefaces4 meida type rendering pdf file in browser. I have successfully tried the example in showcase from primefaces website. Now I want to get a new feature, which offers an tree structure with document nodes in the left panel. User could select one document to display it in the center panel. That means it generates pdf media field in backbean once user selects on one document on the tree.
related code is shown below:
backbean:
@ManagedBean
@ViewScoped
public class DocumentsBean implements Serializable {
private static final long serialVersionUID = 3560539268513760978L;
private TreeNode root;
private String url;
private TreeNode selectedNode;
private StreamedContent media;
public DocumentsBean() {
root = new DefaultTreeNode("Root");
}
public TreeNode getRoot() {
return root;
}
public TreeNode getSelectedNode() {
return selectedNode;
}
public void setSelectedNode(TreeNode selectedNode) {
this.selectedNode = selectedNode;
}
public void onNodeSelect(NodeSelectEvent event) {
File file = (File) this.selectedNode.getData();
generatePDF(file);
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public void explore() {
root = new DefaultTreeNode(new File(this.url), null);
constructDir(root);
}
/**
* construct directory and its sub files.
* @param parent
*/
private void constructDir(TreeNode parent) {
File file = (File) parent.getData();
File[] files = file.listFiles();
for (File f: files) {
if (f.isFile()) {
new DefaultTreeNode("document", f, parent);
} else {
TreeNode subParent = new DefaultTreeNode(f, parent);
constructDir(subParent);
}
}
}
private void generatePDF(File file) {
PDFGenerator generator = new PDFGenerator(file);
File pdf = generator.transformToPDF();
if (pdf != null) {
InputStream stream = null;
try {
stream = new FileInputStream(pdf);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
media = new DefaultStreamedContent(stream, "application/pdf");
}
}
public StreamedContent getMedia() {
return media;
}
}
part of my view:
<p:layoutUnit position="west" size="300" header="Directory Content" resizable="false" collapsible="true">
<h:form id="docTree_form">
<p:growl id="messages" showDetail="true" />
<p:tree id="docTree" value="#{documentsBean.root}" var="node" animate="true" selectionMode="single" selection="#{documentsBean.selectedNode}" dynamic="true" cache="true">
<p:ajax event="select" update=":pdf_form:media" listener="#{documentsBean.onNodeSelect}" />
<p:treeNode expandedIcon="ui-icon-folder-open" collapsedIcon="ui-icon-folder-collapsed">
<h:outputText value="#{node.name}" />
</p:treeNode>
<p:treeNode type="document" icon="ui-icon-document">
<h:outputText value="#{node.name}" />
</p:treeNode>
</p:tree>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="center" header="Center" resizable="true">
<h:form id="pdf_form">
<p:media id="media" value="#{documentsBean.media}" player="pdf" width="100%" height="700px">
Your browser can't display pdf
</p:media>
</h:form>
</p:layoutUnit>
When I run this code, there is no error or exception. However, there is no PDF viewer generated in Firefox. Really strange !
a follow up question based on BalusC comments:
I got this exception when my app is running up:
SEVERE: Servlet.service() for servlet [Faces Servlet] in context with path [/DocumentViewer_JSF] threw exception
java.lang.NullPointerException
at org.primefaces.application.PrimeResourceHandler.handleResourceRequest(PrimeResourceHandler.java:114)
I found that this line causing this exception:
return new DefaultStreamedContent();
If I create a real pdf file, the exception is gone. But I really don't want a pdf file displayed if user has not chosen the file.