a4j:mediaOutput无法呈现PDF

时间:2014-12-29 11:49:43

标签: jsf pdf richfaces ajax4jsf

我的任务是在点击链接时显示从我的JSF应用程序弹出的数据库中提取的PDF。但是我的模态面板不会渲染PDF。相反,我在面板的左上角有一个小的深灰色框。

这是我的XHTML代码:

<rich:column styleClass="viewUserTable">
<f:facet name="header">
    <h:outputText value="Pdf" />
</f:facet>
<h:outputLink value="#" id="link" style="color:blue;margin: 0 auto;">
    Proof
    <rich:componentControl for="panel" attachTo="link"
        operation="show" event="onclick" />
</h:outputLink>
<rich:modalPanel id="panel" width="350" height="100">
    <f:facet name="header">
        <h:outputText value="PDF"></h:outputText>
    </f:facet>
    <a4j:mediaOutput element="object" mimeType="application/pdf"
        id="media" session="false" createContent="#{getMyBean.showPdf}"
        value="1" style="width:800px; height:600px;" cacheable="false"
        standby="loading...">
    </a4j:mediaOutput>
</rich:modalPanel>

这是我在我的bean中调用的方法,用于为<a4j:mediaOutput>创建内容。

public void showPdf(OutputStream stream, Object object) throws SQLException, IOException {

     Blob proof= myObject.getPdf(someValue);//DB call to get the pdf
     InputStream inStream = proof.getBinaryStream();
     int length = -1;
     byte[] buffer = new byte[4096];

     while ((length = inStream.read(buffer)) != -1) {
         stream.write(buffer, 0, length);
     }  
}

我不确定value<a4j:mediaOutput>属性的重要性,但我在互联网上找到了一个示例,其中从DB获取类似内容并且值设置为1.我m使用RichFaces 3.3。

1 个答案:

答案 0 :(得分:0)

我的一个朋友今天来找我这个问题和你一样,我一直在努力想出一个解决方案。经过一段时间研究servlet,我可以解决问题。

您的方法应如下所示:

public void showPdf(OutputStream stream, Object object) throws SQLException, IOException {

    Blob proof = myObject.getPdf(someValue);//DB call to get the pdf

    FacesContext context = FacesContext.getCurrentInstance();
    HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
    ServletOutputStream sout = null;

    response.setContentType("application/pdf");
    //set a constant for a name to avoid cache and duplicate files on server 
    response.setHeader("Content-Disposition","filename=fileName_" + (new Date()).getTime() + ".pdf" );

    response.setHeader("Content-Transfer-Encoding", "binary;");
    response.setHeader("Pragma", " ");
    response.setHeader("Cache-Control", " ");
    response.setHeader("Pragma", "no-cache;");
    response.setDateHeader("Expires", new java.util.Date().getTime());
    //Here you will have to pass to total lengh of bytes
    //as I used a file I called length method
    response.setContentLength(Long.valueOf(  proof.someByteLengthProperty()  ).intValue());

    sout = response.getOutputStream();
    byte[] buf = new byte[4096];
    InputStream is = new FileInputStream(proof.getBinaryStream());
    int c = 0;
    while ((c = is.read(buf, 0, buf.length)) > 0) {
        sout.write(buf, 0, c);
    }
    sout.flush();
    is.close();

}

似乎只写出OutputStream是不够的,所以你必须创建一个ServletOutputStream并将其发送到&#39; FacesContext&#39;所以它可以像输出下载流那样呈现输出。