7 Replies Latest reply on May 27, 2005 2:55 PM by Martin Kultermann

    streaming pdf's from servlet to IE browser not working on JB

    Martin Kultermann Newbie

      Hi everyone, I have an app that generates reports in PDF format and streams them to the client browser from a servlet. The report viewer page has an <embed tag which calls the servlet, which then streams the PDF to the client.

      This works beautifully in my JDEV/OC4J environment. When I deploy to JBOSS 3.2.4 (JVM 1.4.2_03) is stops working and gives me one of these errors:

      File does not start with ?%PDF-? (most frequently)
      The file is damaged and could not be repaired
      File connection timed out

      Any ideas would be greatly appreciated!!!

      I have tried all of the following suggestions gleaned from your and other forums:

      Web.xml:

      <servlet>
      <servlet-name>eStarReport.pdf</servlet-name>
      <servlet-class>com.estar.servlet.eStarImageServlet</servlet-class>
      </servlet>
      <servlet-mapping>
      <servlet-name>eStarReport.pdf</servlet-name>
      <url-pattern>/com.estar.servlet.eStarImageServlet</url-pattern>
      </servlet-mapping>
      
      <mime-mapping>
      <extension>pdf</extension>
      <mime-type>application/pdf</mime-type>
      </mime-mapping>


      Code that streams the pdf :

      arResponse.setContentType("application/pdf");
      arResponse.setHeader( "Content-disposition", "inline; filename=eStarReport.pdf");
      arResponse.setHeader("Cache-Control", "no-cache");
      also tried: arResponse.setHeader( "Cache-Control", "max-age=30");
      also tried :arResponse.setHeader( "Cache-Control", "must-revalidate");
      ByteArrayOutputStream ltestStream = new ByteArrayOutputStream();
      this.outputReportPDF(ltestStream);
      arResponse.setContentLength(ltestStream.toByteArray().length);
      OutputStream lResponseStream = arResponse.getOutputStream();
      ltestStream.writeTo(lResponseStream);
      if (! arResponse.isCommitted()) arResponse.flushBuffer();


      Tag on Report Viewer page:

      <EMBED ID="Report_Object" SRC="eStarReport.pdf;JSESSIONID=2B14CDC409E1B5FC5096B9E0A209009E?REPORT_ID=26526028" width="100%" height="768">



        • 1. Re: streaming pdf's from servlet to IE browser not working o
          avaval Newbie

          Are you closing ByteArrayOutputStream after you are done ? Try closing it at end in your finally block

          finally
          {
          if ( ltestStream != null )
          {

          try
          {
          ltestStream.close()
          ltestStream = null
          }
          catch(IOException eIO )
          {
          //log exception
          }

          }

          }

          • 2. Re: streaming pdf's from servlet to IE browser not working o
            sj_bennett Newbie

             

            response.setContentType("application/pdf");
            response.setHeader( "Content-Disposition ", "inline;filename=myfile.pdf");
            response.setHeader("Pragma", "public");
            response.setHeader("Cache-Control", "max-age=0");
            


            This works for me.

            steve

            • 3. Re: streaming pdf's from servlet to IE browser not working o
              Martin Kultermann Newbie

              Hi everyone, thank you for your suggestions.

              I think I have now determined that the problem lies in the Formula 1 Reporting Engine from Actuate which is throwing NullPointer and ArrayIndex OutOfBounds exceptions in the method that creates and streams the PDF output.

              Can't figure out why it works in my local JDEV/OC4J environment but errors when deployed to JBoss. I figure that something must be missing in the deployment.

              Anyone have any ideas on why it would throw those exceptions in JBoss but not locally in Dev?

              Thanks again for your help...

              • 4. Re: streaming pdf's from servlet to IE browser not working o
                Martin Kultermann Newbie

                Hi everyone again:

                I now know the real problem. It appears that IE is generating a total of three get requests for the <embed tag.

                The logic ended up calling the same routine three times and that is what made the Formula 1 Reporting Engine from Actuate throw those exceptions on the third call.

                I tried adding the Pragma and Cache-Control settings to no avail.

                I added logic to restream the same PDF for each get. No go.

                I also tried to stream a new byte(8096) for the second and third gets. No go.

                Any other ideas woudl be apprciated.

                • 5. Re: streaming pdf's from servlet to IE browser not working o
                  Frank Grimes Newbie

                  This seems to be a known issue with IE.
                  e.g. the jakarta POI FAQ has the following to say on the topic:

                  7. I'm trying to stream an XLS file from a servlet and I'm having some trouble. What's the problem?

                  The problem usually manifests itself as the junk characters being shown on screen. The problem persists even though you have set the correct mime type.

                  The short answer is, don't depend on IE to display a binary file type properly if you stream it via a servlet. Every minor version of IE has different bugs on this issue.

                  The problem in most versions of IE is that it does not use the mime type on the HTTP response to determine the file type; rather it uses the file extension on the request. Thus you might want to add a .xls to your request string. For example http://yourserver.com/myServelet.xls?param1=xx. This is easily accomplished through URL mapping in any servlet container. Sometimes a request like http://yourserver.com/myServelet?param1=xx&dummy=file.xls is also known to work.

                  To guarantee opening the file properly in Excel from IE, write out your file to a temporary file under your web root from your servelet. Then send an http response to the browser to do a client side redirection to your temp file. (Note that using a server side redirect using RequestDispatcher will not be effective in this case)

                  Note also that when you request a document that is opened with an external handler, IE sometimes makes two requests to the webserver. So if your generating process is heavy, it makes sense to write out to a temporary file, so that multiple requests happen for a static file.

                  None of this is particular to Excel. The same problem arises when you try to generate any binary file dynamically to an IE client. For example, if you generate pdf files using FOP, you will come across many of the same issues.



                  • 6. Re: streaming pdf's from servlet to IE browser not working o
                    Frank Grimes Newbie

                    One thing that we did to avoid this problem is to enable caching (TTL of 5 mins.) and tack on a generated "magic number" (a.k.a. timestamp) to the URL.
                    That way, IE re-requests would all be for the same URL and therefore cached, but our own URLs would always change, forcing IE to fetch from the server.

                    Hope I explained that right... had a few pints at the pub tonight. :-)

                    • 7. Re: streaming pdf's from servlet to IE browser not working o
                      Martin Kultermann Newbie

                      Thanks everyone, for your suggestions and Cheers.

                      I finally resolved the problem be removing a response compression filter that was somehow screwing up the pdf output stream.

                      I also found out that the browser is sending 2 GET requests for the <embed tag. The first with a "user-agent=contype" header is used to determine which handler app to load for the data and the second GET requests the actual data. I now trap the first request and just return a content-type=application/pdf header.