0

i am working on a web application with tomcat and java (report generation project). some where i need to create e temporary pdf file to show it to the user as a report preview. i am using this line of code to create my temp file in a temp directory:

 File pdfPath = File.createTempFile("Report",".pdf");

i managed to save the file to that location, the problem is i cant access that file from within my application to show it to user , i am trying to access it with this line in my xhtml file :

<object type="application/pdf" data="/usr/local/tomcat/temp/Report7990394248362823378.pdf" height="600" width="900"></object>

what am i doing wrong? and what is the correct way to do it?

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
MoienGK
  • 4,544
  • 11
  • 58
  • 92
  • It's best to generate and temporarily store the PDF in memory rather than write it to a file. To do this, write the PDF to a `ByteArrayOutputStream` and call `toByteArray()` on it to get the PDF as a `byte[]`. – Muel Jan 26 '14 at 07:42
  • that is a good approach but unfortunately when i do that i cant show the pdf file in a pdf viewer instead the browser tries to download the file – MoienGK Jan 26 '14 at 08:01

1 Answers1

1

The value of the data attribute is wrong. It should represent a (relative) HTTP URL, not a local disk file system path. It's namely the webbrowser who has got to download the content individually once it encounters the value during parsing the retrieved HTML output. It's not the webserver who has got to inline the content from its local disk file system somehow during generating the HTML output, as you seemed to think. That's not how HTTP and HTML works.

So, to fix your problem, just make sure that the value of the data attribute represents a valid HTTP URL. Exactly the one like as you would type in browser's address bar in order to retrieve the content. So, somehow you need to tell your server to return the desired PDF content when a certain URL is been requested.

The easiest way to achieve that is creating a simple file servlet. Here's a kickoff example (obvious error handling such as empty pathinfo, non-existing files, etc omitted for brevity):

@WebServlet("/reports/*")
public class ReportServlet extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String filename = request.getPathInfo().substring(1);
        File file = new File(System.getProperty("java.io.tmpdir"), filename);
        response.setHeader("Content-Type", getServletContext().getMimetype(filename));
        response.setHeader("Content-Length", String.valueOf(file.length()));
        response.setHeader("Content-Disposition", "inline; filename=\"" + filename + "\"");
        Files.copy(file.toPath(), response.getOutputStream());
    }

}

This can then be invoked as follows:

<object type="application/pdf" data="#{request.contextPath}/reports/#{bean.pdfPath.name}" height="600" width="900"></object>

See also:

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • there is only one problem, request.contextPath returns two contextpaths ! my context path is Goli-web and it returns /Goli-web/Goli-web i am replacing one of them with "" but i dont think that is a good practice – MoienGK Jan 26 '14 at 14:48
  • Apparently there's a poorly developed `HttpServletRequestWrapper` in the webapp. – BalusC Jan 26 '14 at 19:00
  • I eliminated the #{request.contextPath} part and now everything is ok. apparently the context path is always printed at the beginning of data url. – MoienGK Jan 27 '14 at 06:24
  • 1
    Great. Keep however in mind that this is not default behavior. – BalusC Jan 27 '14 at 08:52