我正在尝试显示在新浏览器窗口中打开的内联 PDF。我有以下情况:
- 在一些由 ajax 调用的 ActionListen 中,我生成 PDF 内容,将数据放入会话中,并发送要执行的 Javascript(
window.open
打开新页面以显示 PDF) 在打开的页面上,我只有
p:media
标签里面h:body
的值指向StreamedContent
:
现在,在那个页面上我的 PDF 没有生成。在日志中我可以看到这两行:
org.primefaces.application.PrimeResourceHandler handleResourceRequest
SEVERE: Error in streaming dynamic resource. Expression cannot be null
我开始调试并发现了一些东西。
首先,我在我的bean的@PostConstruct
方法中添加了断点。RequestScoped
有趣的是,断点到达了两次,在完美显示 PDF 之后,我大吃一惊?!
经过一些调试后,PrimeResourceHandler
我发现在某些情况下ValueExpression
没有计算,实际上它会抛出NullPointerException
,并且在调试时我再次看到发送了两个请求,第二个请求失败,因为dynamicContentId
在第一个请求中被删除,第二个调用handleResourceRequest
没有有道理。
通过 Firebug,我可以看到两个请求,第一个是 PDF 数据,第二个也是内容类型 application/pdf 但为空,大小为 0。
xhtml页面:
<html>
<h:head></h:head>
<h:body>
<p:media value="#{reportBean.streamedContent}" player="pdf" width="500" height="500"/>
</h:body>
</html>
后备豆:
@RequestScoped
public class StampaListeBackingBean implements Serializable {
private static final long serialVersionUID = 1L;
private StreamedContent streamedContent;
@PostConstruct
public void init() {
Map<String, Object> session = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
byte[] b = (byte[]) session.get("reportBytes");
if (b != null) {
streamedContent = new DefaultStreamedContent(new ByteArrayInputStream(b), "application/pdf");
}
}
public StreamedContent getStreamedContent() {
if (FacesContext.getCurrentInstance().getRenderResponse()) {
return new DefaultStreamedContent();
} else {
return streamedContent;
}
}
public void setStreamedContent(StreamedContent streamedContent) {
this.streamedContent = streamedContent;
}
}
我需要了解为什么在带有p:media
标签的页面上发送两个请求,并弄清楚如何使其工作。支持 bean 是请求范围的,它StreamedContent
在@PostConstruct
方法中创建,并具有该字段的 getter 和 setter。Primefaces 版本是 3.4.2,Mojarra 是 2.1.14。
添加:
很容易重现我的问题。如果init
方法中的代码替换为以下内容:
FileInputStream fis = new FileInputStream(new File("C:\\samplexxx.pdf"));
streamedContent = new DefaultStreamedContent(fis, "application/pdf");
问题可以重现。