4 Replies Latest reply on Nov 29, 2010 9:46 AM by Lynn Ford

    PDF generation using HttpServletResponse and AJAX status

    Lynn Ford Newbie

      Hello all! First, thanks to all for the great forum content. It's been invaluable as I get up to speed on RichFaces.

       

      Here's my dilemna...

       

      Problem1: I cannot get HttpServletResponse-based method that generates PDFs as attachments to display correctly in the browser using a:commandButton. It displays the file itself (basically garbage from the user's perspective). The rest of our site relies on a:commandButton to implement a AJAX status spinner.

       

      Solution1: Use h:commandButton instead which correctly results in the browser recognizing the attachment as a PDF. Functionally this is acceptable. But this results in a secondary issue.

       

      Problem2: When using h:commandButton to display PDFs correctly, AJAX events are not being sent to trigger the status spinner. So on PDF generations that are a bit longer, the user has no indication that the process is still in-progress.

       

      Solution2: Use a:commandButton. I've attempted a number of alternative approaches like using a:support to detect onclick events which can generate the PDF but without the POST I believe nothing ever gets displayed. Also tried is commandLink etc. but with no luck.

       

      Can anyone get me steered in the right direction? Any ideas?

       

      Below is my code fragments. Essentionally, very similar to other implementations I've found.

       

      Thanks in advance.

      Lynn

       

      ReportsBean.java

       

      // set database connection, generate the pdf report with above params, and write out the

       

      // servlet response

      FacesContext facesContext = FacesContext.getCurrentInstance();

       

      if (!facesContext.getResponseComplete()) {

      Connection dbConnection = DBConnection.getSqlServerConnection();

       

      byte[] pdfChart = JasperRunManager.runReportToPdf(this.getClass().getResourceAsStream("/reports/" + makeReportName() + ".jasper"), parameters, dbConnection);

       

       

       

       

      log.info("generated pdf: size = " + pdfChart.length);

      HttpServletResponse response = (HttpServletResponse) facesContext

      .getExternalContext().getResponse();

      response.reset();

      response.setContentType(

      "application/pdf");

      response.addHeader(

      "Content-Disposition","attachment;filename=" + makeReportName() + ".pdf");

      response.setContentLength(pdfChart.

      length);

      ServletOutputStream servletOutputStream = response.getOutputStream();

      servletOutputStream.write(pdfChart, 0, pdfChart.

      length);

      servletOutputStream.flush();

      servletOutputStream.close();

      facesContext.responseComplete();

      }

       

      reports.xhtml (wrapped in h:form and a:region)

       

      <center><a:commandButton id="queryReport" value="Submit Query" action="#{Reports.generate()}"/>&#160;&#160;&#160;

       

      <a:status id="statusFuelPricesRegion">

       

      <f:facet id="StartStatusRegion" name="start">

       

      <h:graphicImage id="SpinnerGifRegion" value="/img/spinner.gif" />

       

      </f:facet>

       

      </a:status></center>

       

       

        • 1. Re: PDF generation using HttpServletResponse and AJAX status
          Ilya Shaikovsky Master

          1) a4j:* controls can't be used for that. It's known limitation.

           

          2) to showstatus use just js. Next points should be considered:

          • status outside regions has _viewRoot:status id
          • status inside regions(with any nesting) has <parentRegionId>:status id
          • statuses facets has next id's : <statusId>.start and <statusId>.stop

           

          so just show start facet and hide stop facet. so status will be there and after page refresh - it will be switched to stop by itself because of reinitializing..

           

          example:

          <a4j:status id="commonstatus"  startText="In progress..." stopText="Complete"/>
          <br />
          <rich:spacer height="5" />
          <a4j:region id="r1">
          <a4j:region id="r2">
          <script>
          function switchStatus(){
          document.getElementById('_viewRoot:status.start').style.display='inline';
          document.getElementById('_viewRoot:status.stop').style.display='none';
          }
          </script>
          <h:form>
          <h:commandButton eventsQueue="foo"  value="Ajax Request" onclick="switchStatus();"/>
          </h:form>

          <a4j:status id="commonstatus"  startText="In progress..." stopText="Complete"/>

           

          <script>

          function switchStatus(){

          document.getElementById('_viewRoot:status.start').style.display='inline';

          document.getElementById('_viewRoot:status.stop').style.display='none';

          }

          </script>

          <h:form>

            <h:commandButton value="Common Request with status" onclick="switchStatus();"/>

          </h:form>

          • 4. Re: PDF generation using HttpServletResponse and AJAX status
            Lynn Ford Newbie

            Bit more help please. Status start works ok now, but never stops. I suppose the reinit you speak of is not occurring? Can I determine when my action has completed to switch status and/or force refresh?

             

            Thanks in advance.

             

            Revised:

            <

            script>

            function

             

            switchStatus(){

            document.getElementById(

            'fuelPricesRegion:status.start').style.display='inline';

            document.getElementById(

            'fuelPricesRegion:status.stop').style.display='none';

            }

            </

            script>

             

            <center><h:commandButton id="queryReport" eventsQueue="fpQueue" value="Submit Query" action="#{Reports.generate()}" onclick="switchStatus();"/>&#160;&#160;&#160;

             

            <a:status id="statusFuelPricesRegion">

             

            <f:facet id="StartStatusRegion" name="start">

             

            <h:graphicImage id="SpinnerGifRegion" value="/img/spinner.gif" />

             

            </f:facet>

             

            </a:status></center>