Why doesn'n create pdf-documents in java servl

2019-03-07 16:31发布

问题:

This question already has an answer here:

  • How can I serve a PDF to a browser without storing a file on the server side? 4 answers

I use iText/Pdfbox to create a PDF document. Everything works when I create the PDF using a standalone Java class like this:

public static void main(String[] args){
...
...
...
}

The document is created correctly.

But I need create a PDF document from a Servlet. I paste the code into the get or post method, run that servlet on the server, but the PDF document isn't created!

This code works as a standalone application:

This code doesn't work:

回答1:

Please read the documentation. For instance the answer to the question How can I serve a PDF to a browser without storing a file on the server side?

You are currently creating a file on your file system. You aren't using the response object, meaning you aren't sending any bytes to the browser. This explains why nothing happens in the browser.

This is a simple example:

public class Hello extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        response.setContentType("application/pdf");
        try {
            // step 1
            Document document = new Document();
            // step 2
            PdfWriter.getInstance(document, response.getOutputStream());
            // step 3
            document.open();
            // step 4
            document.add(new Paragraph("Hello World"));
            document.add(new Paragraph(new Date().toString()));
            // step 5
            document.close();
        } catch (DocumentException de) {
            throw new IOException(de.getMessage());
        }
    }
}

However, some browsers experience problems when you send bytes directly like this. It's safer to create the file in memory using a ByteArrayOutputStream and to tell the browser how many bytes it can expect in the content header:

public class PdfServlet extends HttpServlet {

    protected void service(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {
        try {
            // Get the text that will be added to the PDF
            String text = request.getParameter("text");
            if (text == null || text.trim().length() == 0) {
                 text = "You didn't enter any text.";
            }
            // step 1
            Document document = new Document();
            // step 2
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PdfWriter.getInstance(document, baos);
            // step 3
            document.open();
            // step 4
            document.add(new Paragraph(String.format(
                "You have submitted the following text using the %s method:",
                request.getMethod())));
            document.add(new Paragraph(text));
            // step 5
            document.close();

            // setting some response headers
            response.setHeader("Expires", "0");
            response.setHeader("Cache-Control",
                "must-revalidate, post-check=0, pre-check=0");
            response.setHeader("Pragma", "public");
            // setting the content type
            response.setContentType("application/pdf");
            // the contentlength
            response.setContentLength(baos.size());
            // write ByteArrayOutputStream to the ServletOutputStream
            OutputStream os = response.getOutputStream();
            baos.writeTo(os);
            os.flush();
            os.close();
        }
        catch(DocumentException e) {
            throw new IOException(e.getMessage());
        }
    }
}

For the full source code, see PdfServlet. You can try the code here: http://demo.itextsupport.com/book/

You wrote in a comment

This demo writes the PDF file into the browser. I want to save the PDF on my hard drive.

This question could be interpreted in two different ways:

  1. You want to write the file to a specific directory on the user's disk drive without any user interaction. This is forbidden! It would be a serious security hazard if a server could force a file to be written anywhere on a user's disk drive.
  2. You want to show a dialog box so that the user can save the PDF on his disk drive in a directory of his choice instead of just showing the PDF in the browser. In this case, please take a closer look at the documentation. You'll see this line: response.setHeader("Content-disposition","attachment;filename="+ "testPDF.pdf"); You can set the Content-disposition to inline if you want the PDF to open in the browser, but in the question, the Content-disposition is set to attachment which triggers a dialog box to open.

See also How to show a Save As dialog for a iText generated PDF?