I'm generating a PDF in a Java EE web application, with the intention of then linking the user to it. I am of the understanding that accessing the file system from Java EE is not recommended due to possible issues wit accessibility on distributed systems etc. This should not be an issue, as this will always be run on a single server. However, I am wondering the best way to achieve what I'm aiming for.
I do not need the file to stay afterwards, it can be a temp file, or anything of that nature. I simply need to know what to do with the file I have generated.
I am using PDFBox to generate the PDF.
I am have tried storing it on the file system relative to the root, however I am working on windows with NetBeans so that is proving problematic. The server is of course Linux based, and I have not tested that yet. It may well work on the server, I just struggle to understand why this would not work on Windows. By 'not work' I mean that when I store the file, I am using this code:
myDocument.save("/var/PDFTEST2.pdf");
and it is saving the file in C:/var/PDFTEST2.pdf, however this is inacceible from the running application.
My questions are:
What is the considered acceptable way to store and present generated files in a Java EE application? If it's what I'm doing (which I doubt), then is it possible to get this working in Windows?
Thank-you for your time.
Solution: I solved it thanks to the suggestion of streaming the file to the response. PDFBox allows you to 'save' directly to an output stream:
ByteArrayOutputStream output = new ByteArrayOutputStream();
PDDocument myDocument = new PDDocument();
//Populate PDDocument...
myDocument.save(output);
myDocument.close();
response.setContentType("application/pdf");
//response.addHeader("Content-Type", "application/force-download"); //--< Use this if you want the file to download rather than display
response.addHeader("Content-Disposition", "inline; filename=\"yourFile.pdf\"");
response.getOutputStream().write(output.toByteArray());
Worked beautifully!
It is not accessible because it is not part of the web root folder, so the webserver/container cannot service that file through the web. But you are free to add a servlet which reads the PDF from disc and streams it to the response. A Google for 'FileServlet' or 'ImageServlet' will give you countless examples to copy/paste from.
Common example: http://balusc.blogspot.nl/2009/02/fileservlet-supporting-resume-and.html
What about creating a temp file using File.createTempFile()
? Here is an example taken from here:
public void parse(
InputStream stream, ContentHandler handler,
Metadata metadata, ParseContext context)
throws IOException, SAXException, TikaException {
File tmpFile = File.createTempFile("pdfbox-", ".tmp", null);
RandomAccess scratchFile = new RandomAccessFile(tmpFile, "rw");
PDDocument pdfDocument =
PDDocument.load(new CloseShieldInputStream(stream), scratchFile, true);
try {
if (pdfDocument.isEncrypted()) {
try {
String password = metadata.get(PASSWORD);
if (password == null) {
password = "";
}
pdfDocument.decrypt(password);
} catch (Exception e) {
// Ignore
}
}
metadata.set(Metadata.CONTENT_TYPE, "application/pdf");
extractMetadata(pdfDocument, metadata);
PDF2XHTML.process(pdfDocument, handler, metadata, extractAnnotationText, enableAutoSpace);
} finally {
pdfDocument.close();
scratchFile.close();
tmpFile.delete();
}
}
Take a look at temp.deleteOnExit();
P.S.: There is a bug in Java Versions between 1.7.0_25 and 1.7.0_45 where the temp files doesn't work properly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With