a4j:mediaOutput not rendering PDF

风流意气都作罢 提交于 2019-12-02 17:29:01

问题


I have a task of displaying a PDF fetched from the database as a pop up in my JSF application upon clicking a link. However my modal panel isn't rendering the PDF. Instead I get a small dark grey box at the top left corner of the panel.

Here's my XHTML code:

<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>

Here's the method I'm calling in my bean to create content for <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);
     }  
}

I am not sure of the significance of the value attribute in the <a4j:mediaOutput> but I found an example on internet where similar content was being fetched from DB and and the value was set as 1. I m using RichFaces 3.3.


回答1:


A friend of mine came to me with this problem today and like you I've struggled to come up with a solution. After some time studying servlet I could solve the problem.

Your method should look like:

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();

}

It seems that only writing out the OutputStream is not enough so you have to create a ServletOutputStream and send it throghout the 'FacesContext' so it can render the output as if it was sending a download stream.



来源:https://stackoverflow.com/questions/27688304/a4jmediaoutput-not-rendering-pdf

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!