- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我遇到了与浏览器中 Primefaces4 meida 类型渲染 pdf 文件相关的问题。我已经成功尝试了 primefaces 网站展示中的示例。现在我想要一个新功能,它提供了一个树结构,左侧面板中带有文档节点。用户可以选择一个文档将其显示在中央面板中。这意味着一旦用户选择树上的一个文档,它就会在 backbean 中生成 pdf 媒体字段。
相关代码如下:
后台 bean :
@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;
}
}
我的部分观点:
<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>
当我运行此代码时,没有错误或异常。但是,Firefox 中没有生成 PDF 查看器。真是奇怪!
基于 BalusC 评论的后续问题:
当我的应用程序运行时,我遇到了这个异常:
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)
我发现这一行导致了这个异常:
return new DefaultStreamedContent();
如果我创建一个真正的 pdf 文件,异常就会消失。但如果用户没有选择文件,我真的不希望显示 pdf 文件。
最佳答案
您的具体问题是因为网络浏览器实际上是在物理上完全独立的 HTTP 请求中下载 PDF 文件,而不是基于 JSF 源代码生成和发送 HTML 输出的 HTTP 请求。您可能已经知道 View 作用域 bean 通过 javax.faces.ViewState
绑定(bind)到特定的 JSF View 。隐藏输入字段。如果此更改或不存在,则请求将获得一个新的不同 View 范围 bean 实例。
换句话说,当浏览器通过单独的 HTTP 请求从服务器下载 PDF 文件时,它并没有使用相同的 @ViewScoped
bean 实例,而是获得一个全新且完全独立的实例,该实例不具有与绑定(bind)到页面的属性(状态)相同的属性(状态),因此整个 StreamedContent
就是null
就在那时。
此问题与 <p:media>
和StreamedContent
与 <p:graphicImage>
的问题本质上有相同的理由和StreamedContent
之前已经回答过好几次了:
在您的特定情况下,您需要以 DocumentsBean
的方式重新设计整个集合。支持 bean 通过唯一标识符将 PDF 文件存储在某个位置(例如临时磁盘、服务器内存、数据库等),然后将该唯一标识符作为请求参数传递给 <p:media>
如下:
<p:media value="#{mediaManager.stream}" width="100%" height="700px" player="pdf">
<f:param name="id" value="#{documentsBean.mediaId}" />
</p:media>
据此MediaManager
支持 bean 看起来像这样:
@ManagedBean
@ApplicationScoped
public class MediaManager {
@EJB
private MediaService service;
public StreamedContent getStream() throws IOException {
FacesContext context = FacesContext.getCurrentInstance();
if (context.getCurrentPhaseId() == PhaseId.RENDER_RESPONSE) {
// So, we're rendering the HTML. Return a stub StreamedContent so that it will generate right URL.
return new DefaultStreamedContent();
} else {
// So, browser is requesting the media. Return a real StreamedContent with the media bytes.
String id = context.getExternalContext().getRequestParameterMap().get("id");
Media media = service.find(Long.valueOf(id));
return new DefaultStreamedContent(new ByteArrayInputStream(media.getBytes()));
}
}
}
关于pdf - PrimeFaces p :media not working with StreamedContent in a @ViewScoped bean,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18994288/
我已经实现了两个 StreamedContent bean 来动态加载图形图像,按照找到的解决方案 here 1)第一个我在 contentFlow 中显示图像(一切正常)
这是我在论坛上的第一个问题,我希望你能帮助我解决这个问题。我的escenary: 基于我想从浏览器下载的文件 我正在使用 primefaces、FileDownload 和 StreamedConte
我正在尝试显示在数据库中保存为 StreamedContent 的图像字节在如下: private StreamedContent content; // getter and setter pub
returning StreamedContent 的具体 URL
为了使用灯箱,我需要一个指向由 生成的图像的链接。 . 最终,HTML 应如下所示: 到目前为止,这是我的 JSF 尝试: 如何获取的具体网址返回 Streame
这个问题在这里已经有了答案: Display dynamic image from database or remote source with p:graphicImage and Streamed
我遇到了与浏览器中 Primefaces4 meida 类型渲染 pdf 文件相关的问题。我已经成功尝试了 primefaces 网站展示中的示例。现在我想要一个新功能,它提供了一个树结构,左侧面板中
我在 C:/Reports/report.pdf 中有一个 pdf,我需要使用 primefaces 下载它。正如我所读到的,我需要首先获取文件的 InputStream 并使用 DefaultStr
我有一个带有 StreamedContent 的对象列表属性,我需要在 中显示它组件。 但这并没有显示出来。它显示替代文本。我看到了另一个帖子 Use of p:graphi
我是一名优秀的程序员,十分优秀!