Невозможно отобразить PDF в p: мультимедиа, созданный из потокового контента в Primefaces
Я пытаюсь показать встроенный PDF, который открывается в новом окне браузера. У меня есть следующий сценарий:
В некотором ActionListen, который вызывается ajax, я генерирую содержимое 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
Я начал отлаживать и узнавать несколько вещей.
Сначала я добавил точку останова@PostConstruct
метод моегоRequestScoped
боб. Интересно, что точка останова достигается дважды, и, к моему большому удивлению, после этого PDF-файл отображается идеально ?!
После некоторой отладкиPrimeResourceHandler
Я понимаю, что в некоторых случаяхValueExpression
не рассчитывается, на самом деле он бросаетNullPointerException
и снова во время отладки я увидел, что два запроса отправляются, а второй запрос не выполняется, потому чтоdynamicContentId
удаляется в первом запросе и втором вызовеhandleResourceRequest
не имеет смысла
Через Firebug я вижу два запроса, первый из которых хорош для данных PDF, а второй - также для типа содержимого application / pdf, но пустой, с размером 0.
HTML-страница:
<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
тег, и выяснить, как заставить это работать. Бэк-бин является областью запроса, он создаетStreamedContent
в@PostConstruct
метод, и имеет геттер и сеттер для этого поля. Версия Primefaces - 3.4.2, с Мохаррой 2.1.14.
ДОБАВЛЕНО:
Это легко воспроизвести мою проблему. Если код вinit
метод заменяется следующим:
FileInputStream fis = new FileInputStream(new File("C:\\samplexxx.pdf"));
streamedContent = new DefaultStreamedContent(fis, "application/pdf");
проблема может быть воспроизведена.