0

I want to view a pdf file that is stored as a blob in my Oracle Database. I'm using a <p:media/> in the xhml , and StreamedContent in the backing bean.

Here is xhtml

<ui:composition xmlns="http://www.w3.org/1999/xhtml"
  xmlns:ui="http://java.sun.com/jsf/facelets"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:c="http://java.sun.com/jsp/jstl/core"
  xmlns:p="http://primefaces.org/ui">

 <p:outputPanel id="outputPanelDialogShowPdf">

    <div style="text-align: center">
        <p:media value="#{bean.media}" width="600px" height="300px" player="pdf" />
    </div>

    <p:spacer height="1px" />
    <div style="text-align: center">
        <p:commandButton value="#{msgs.button_cancel}" icon="ui-icon-cancel" oncomplete="dialogShowPdf.hide();" 
                         action="#{bean[cancelAction]}" immediate="true" />
    </div>
</p:outputPanel>

And here is the action button (which is part of data table) which calls the action bean

    <p:commandButton value="Show PDF"
                              update=":formMediaDataDialogShowPdf:outputPanelDialogShowPdf" 
                              oncomplete="PF('dialogShowPdf').show()" 
                              action="#{ bean.showPdfAction }" rendered="#{ mediaData.mediaType == 'application/pdf'}"> 
                 <f:setPropertyActionListener value="#{mediaData}" target="#{bean.selectedMediaData}" />
            </p:commandButton> 

And this is the action in the bean

public void showPdfAction(){

    if (null != selectedMediaData) { 
        media = new DefaultStreamedContent(new ByteArrayInputStream(selectedMediaData.getMediaData()),"application/pdf");   
    }
}

The problem is that the media is not being displayed even though the action in the bean runs without errors, and the media property in the bean is being properly initialized.

Can anyone provide some help for that

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
doubleH90
  • 163
  • 4
  • 17

1 Answers1

0

After several hours of research, I found a solution that worked quite well with me.

I have updated the action in the bean as follows

if (null != selectedMediaData) { 
    FacesContext facesContext = FacesContext.getCurrentInstance();
    HttpSession session = (HttpSession) facesContext.getExternalContext().getSession(false);

    session.setAttribute("pdfBytesArray", selectedMediaData.getMediaData());
}

Now as I'm passing pdfBytesArray as a session attribute, I've created a servlet where I can get this attribute from the session and then process the byte array then writing it to response stream with a content type of application/pdf

public class PdfPreviewServlet extends HttpServlet {
private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    byte[] pdfBytesArray = (byte[]) request.getSession().getAttribute("pdfBytesArray");
    request.getSession().removeAttribute("pdfBytesArray");
    response.setContentType("application/pdf");
    response.setContentLength(pdfBytesArray.length);
    response.getOutputStream().write(pdfBytesArray);
} }

Then annotated the servlet with @WebServlet("/pdfPreviewServlet")

Then changed <p:media/> to <p:media value="/pdfPreviewServlet" player="pdf"/>

doubleH90
  • 163
  • 4
  • 17