【问题标题】:Message: Missing PDF in PrimeFaces Extnsions DocumentViewer消息:PrimeFaces 扩展 DocumentViewer 中缺少 PDF
【发布时间】:2018-10-24 03:44:04
【问题描述】:

我在使用 PrimeFaces 6.2 和 MyFaces 2.2.12 的 Primefaces Extensions (6.2.9) 的 DocumentViewer 中显示 StreamedContent PDF 时遇到问题。我读了同样的问题,但这是另一种情况。

Message: Missing PDF in PrimeFaces Extensions DocumentViewer

这是我的 xhtml 代码

<p:commandButton icon="fa fa-print" actionListener="#{bean.onPrerender}" />

对话框代码

<p:dialog id="dvDialog" widgetVar="dv_dialog" dynamic="true" header="Document" width="1200px" height="700px" modal="true">
     <pe:documentViewer cache="true" height="500" value="#{bean.content}" download="report.pdf" />
</p:dialog>

这是我的java代码

private StreamedContent content;

public void onPrerender(ActionEvent actionEvent) {

    try {

        ByteArrayOutputStream out = new ByteArrayOutputStream();

        Document document = new Document();
        PdfWriter.getInstance(document, out);
        document.open();

        for (int i = 0; i < 50; i++) {
            document.add(
                  new Paragraph("All work and no play makes Jack a dull boy"));
        }

        document.close();
        // content = new DefaultStreamedContent(
        // new ByteArrayInputStream(out.toByteArray()), "application/pdf");
        content = new ByteArrayContent(out.toByteArray(), "application/pdf");
    } catch (Exception e) {
        e.printStackTrace();
    }

    PrimeFaces.current().executeScript("PF('dv_dialog').show()");

}

public StreamedContent getContent() {
    return content;
}

public void setContent(StreamedContent content) {
    this.content = content;
}

错误信息

PDF.js v1.10.88 (build: c62a1938)
Message: Missing PDF "http://localhost:8080/hoft/javax.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&v=6.2&pfdrid=1a55ef4c9448951fae5f493579cf80e1&pfdrt=sc&pfdrid_c=true&download=report.pdf".

有任何线索,我的代码有什么问题?它实际上是demo中的代码,展示了Primeface-Extensions的修改。

我的项目使用 iframe,文档查看器将显示在弹出对话框中。我也尝试了@SessionScoped 和@ViewScoped,但没有运气。

如果我在独立项目中尝试它,它可以工作(没有 iframe)。可能有人可以提供线索,如何调试才能找到问题。

请帮忙....谢谢。

我收到错误消息

pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:17581 GET http://localhost:8081/hoft/javax.faces.resource/dynamiccontent.properties.xhtml?ln=primefaces&v=6.2&pfdrid=3c954d24c76c30714a581092c23e1489&pfdrt=sc&pfdrid_c=true&download=report.pdf 404
PDFFetchStreamReader @ pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:17581
getFullReader @ pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:17527
(anonymous) @ pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:4388
(anonymous) @ pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:1002
resolveCall @ pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:1001
_createStreamSink @ pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:1266
MessageHandler._onComObjOnMessage @ pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:1094
pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:19633 Uncaught (in promise) Error: Missing PDF file.
    at pdf.viewer.js.xhtml?ln=primefaces-extensions&v=6.2.9:19633

【问题讨论】:

  • 结果代码 404
  • 该消息是否在页面加载或按钮按下时出现?如果存在,请为异常提供完整的堆栈跟踪。您在大括号中提到的 IFrame 在哪里?
  • 按下按钮后出现。我粘贴错误消息。
  • 这看起来像是来自网络浏览器的错误日志。按下按钮时,servlet 容器(服务器端)是否输出或记录带有堆栈跟踪的 Java 异常?
  • 我不认为你可以做你正在做的事情。如果您查看它实际呈现的 DocumentViewer 组件,并使用 IFRAME 将文档查看器放入其中。您现在在 IFRAME 中使用 IFRAME,这一定是搞砸了?如果它独立工作,那么你必须一次删除一个变量,直到你弄清楚是什么破坏了它。

标签: java jsf primefaces primefaces-extensions


【解决方案1】:

我试过这个:

  1. Java EE 7
  2. GlassFish 4.1.2
  3. PrimeFaces 6.2
  4. PrimeFaces-Extensions 6.2.9

在bean(类)代码处:

@ManagedBean
@ApplicationScoped
public class DocumentViewerController {

范围是@ApplicationScoped。我有一个私有的 StreamedContent 属性。以及两个主要的公共方法:

第一种方法:p:commandButton的actionListener属性调用。该方法接收一个参数(在我的例子中)。

public void onPrerender(Tramite tramite) {    
    tramiteSelected = tramite;
    numeroTramite = tramite.getNumero();
    contrato = tramite.getContrato();
} 

第二种方法:它是在对话框组件中的 pe:documentViewer 中使用的,如下所示:

<pe:documentViewer id="certificadoViewer"
                   height="500px"
                   width="750px"
                   cache="false"
                   value="#{documentViewerController.certificado}"
                   download="certificado_#{documentViewerController.numero}_#{documentViewerController.contrato}.pdf" />

注意:第二种方法就像一个属性(getter 和 setter)。这就是诀窍。

我项目的最终代码是:

# Bean (DocumentViewerController.java):

package com.epmrpsd.certificado.consulta.controladores;

import com.epmrpsd.certificado.consulta.controladores.util.JsfUtil;
import com.epmrpsd.certificado.consulta.entidades.Tramite;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import javax.faces.bean.ApplicationScoped;
import javax.faces.bean.ManagedBean;
import org.primefaces.model.DefaultStreamedContent;
import org.primefaces.model.StreamedContent;

/**
 *
 * @author pbonilla
 */
@ManagedBean
@ApplicationScoped
public class DocumentViewerController {

    private StreamedContent content;
    private Integer numeroTramite;
    private Integer contrato;
    private Tramite tramiteSelected;

    // Path where the file exists
    private String pdfPathDirectory = "C:\\Users\\<user>\\certificados\\";

    public void onPrerender(Tramite tramite) {

        tramiteSelected = tramite;
        numeroTramite = tramite.getNumero();
        contrato = tramite.getContrato();
    }

    public StreamedContent getCertificado() {

        InputStream stream = null;
        try {
            File file = new File(pdfPathDirectory + numeroTramite + "_" + contrato + ".pdf");

            if (file.exists()) {
                stream = new FileInputStream(file);
            } else {
                JsfUtil.addErrorMessage("Error", "No se ha encontrado el archivo");
            }
            this.content = new DefaultStreamedContent(stream, "application/pdf");
        } catch (FileNotFoundException fnfex) {
            JsfUtil.addErrorMessage("Error", "No se ha encontrado el archivo. Error: " + fnfex.getMessage());
            fnfex.printStackTrace();
        } catch (Exception e) {
            JsfUtil.addErrorMessage("Error", "Se ha generado un error al cargar el certificado. Error: " + e.getMessage());
            e.printStackTrace();
        }

        return content;
    }

    public void setCertificado(StreamedContent contenido) {
        content = contenido;
    }

    public Tramite getTramiteSelected() {
        return tramiteSelected;
    }

    public void setTramiteSelected(Tramite tramiteSelected) {
        this.tramiteSelected = tramiteSelected;
    }

    public Integer getNumero() {
        return numeroTramite;
    }

    public void setNumero(Integer numeroTramite) {
        this.numeroTramite = numeroTramite;
    }

    public Integer getContrato() {
        return contrato;
    }

    public void setContrato(Integer contrato) {
        this.contrato = contrato;
    }

}

#视图(index.xhtml):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:ui="http://java.sun.com/jsf/facelets"
      xmlns:pe="http://primefaces.org/ui/extensions">
    <h:head>
        <title>Consulta de Certificados Digitales</title>
        <h:outputStylesheet library="css" name="epmrpsd.css" />
        <h:outputStylesheet library="webjars" name="font-awesome/5.5.0/css/all-jsf.css" />
        <h:outputStylesheet library="css" name="jsfcrud.css"/>
        <h:outputScript library="js" name="jsfcrud.js"/>
        <link rel="shortcut icon" type="image/png" href="#{resource['images/logo.png']}"/>
    </h:head>
    <h:body>
        <div id="background" style="position: fixed;">
            <h:form id="formCertificados">

                <div class="ui-g" style="margin-top: 25px;">
                    <div class="ui-g-1"></div>
                    <div class="ui-g-10">
                        <p:growl id="mensajes" />

                        <Extra code> ...

                        <p:outputPanel id="pnlCertificado">
                            <p:dataTable id="tramitesTable"
                                         value="#{tramiteController.items}"
                                         var="tramite"
                                         rowKey="#{tramite.id}"
                                         selectionMode="single"
                                         selection="#{tramiteController.selected}"
                                         emptyMessage="No se encontraron trámites con los criterios dados"
                                         rows="10"
                                         rowsPerPageTemplate="10,20,30,40,50">

                                <p:column headerText="Número Trámite" >
                                    <h:outputText value="#{tramite.numero}" />
                                </p:column>

                                <p:column headerText="Descripción" >
                                    <h:outputText value="#{tramite.tipo.descripcion}" />
                                </p:column>

                                <p:column headerText="Número Contrato" >
                                    <h:outputText value="#{tramite.contrato}" />
                                </p:column>

                                <p:column style="text-align: center" headerText="Acción" >
                                    <center>
                                        <p:commandButton id="viewCertificado"
                                                         styleClass="ui-priority-primary"
                                                         value="Ver certificado"
                                                         actionListener="#{documentViewerController.onPrerender(tramite)}"
                                                         update=":ViewCertificadoForm"
                                                         oncomplete="PF('ViewCertificadoDialog').show()" />
                                    </center>
                                </p:column>
                            </p:dataTable>
                        </p:outputPanel>
                    </div>
                    <div class="ui-g-1"></div>
                </div>
            </h:form>

            <ui:include src="ViewCertificado.xhtml"/>
        </div>
    </h:body>
</html>

视图的最后一个组件是(ViewCertificado.xhtml):

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:f="http://xmlns.jcp.org/jsf/core"
      xmlns:p="http://primefaces.org/ui"
      xmlns:pe="http://primefaces.org/ui/extensions">

    <ui:composition>

        <p:dialog id="ViewCertificadoDlg"
                  widgetVar="ViewCertificadoDialog"
                  modal="true"
                  resizable="false"
                  appendTo="@(body)"
                  header="Certificado #{documentViewerController.contrato}">
            <h:form id="ViewCertificadoForm">
                <h:panelGroup id="display">
                    <p:panelGrid columns="1" rendered="#{documentViewerController.tramiteSelected != null}">
                        <pe:documentViewer id="certificadoViewer"
                                           height="500px"
                                           width="750px"
                                           cache="false"
                                           value="#{documentViewerController.certificado}"
                                           download="certificado_#{documentViewerController.numero}_#{documentViewerController.contrato}.pdf" />
                    </p:panelGrid>
                    <p:commandButton value="Cerrar" onclick="ViewCertificadoDialog.hide()"/>
                </h:panelGroup>
            </h:form>
        </p:dialog>

    </ui:composition>
</html>

【讨论】:

    猜你喜欢
    • 2019-01-28
    • 2016-02-04
    • 2017-05-09
    • 1970-01-01
    • 2011-10-07
    • 2017-01-05
    • 2010-11-13
    • 2013-05-21
    • 1970-01-01
    相关资源
    最近更新 更多