2014-12-29 111 views
0

我有一个任务,显示从数据库中提取的PDF作为弹出在我的JSF应用程序中点击链接。但是,我的模式面板不会渲染PDF。相反,我在面板的左上角看到一个黑灰色的小方框。a4j:mediaOutput not rendering 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> 

这里是我打电话给我的豆为<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); 
    } 
} 

我不知道在<a4j:mediaOutput>value属性的重要性,但我发现一个例子互联网上有类似的内容是被取出从DB和和值设为1时我米使用RichFaces的3.3 。

回答

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并发送throghout的“FacesContext的”,因此它可以使输出如果它正在发送下载流。