Question on Java Servlet to open a PDF file using

2019-03-03 15:17发布

问题:

The code below grabs a PDF file and displays it in the browser.

import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintWriter;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.lowagie.text.Document;
import com.lowagie.text.DocumentException;
import com.lowagie.text.pdf.PdfReader;
import com.lowagie.text.pdf.PdfStamper;
import com.lowagie.text.pdf.PdfStream;
import com.lowagie.text.pdf.PdfWriter;

public class WelcomeServlet extends HttpServlet {

    private static final String DOCUMENT_LOCATION = "H:\\testPDF.pdf"; // a test pdf on my PC

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        PdfReader reader = new PdfReader(DOCUMENT_LOCATION);
        PdfStamper stamper = null;
        try {
            stamper = new PdfStamper(reader, baos);
        } catch (DocumentException e) {
            e.printStackTrace();
        }
        try {
            stamper.close();
        } catch (DocumentException e) {
            System.out.println("Why is it making me do this?");
            e.printStackTrace();
        }

        // set some response headers
        response.setHeader("Expires", "0");
        response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
        response.setHeader("Pragma", "public");
        response.setContentType("application/pdf");
        response.setContentLength(baos.size());

        OutputStream os = response.getOutputStream();
        baos.writeTo(os);
        os.flush();
        os.close();

    }
} 

If I change it to this code, it doesn't return the file. The only difference are the lines that deal with PdfStamper are removed.

import java.io.ByteArrayOutputStream;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.io.PrintWriter;

    import javax.servlet.ServletConfig;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;

    import com.lowagie.text.Document;
    import com.lowagie.text.DocumentException;
    import com.lowagie.text.pdf.PdfReader;
    import com.lowagie.text.pdf.PdfStamper;
    import com.lowagie.text.pdf.PdfStream;
    import com.lowagie.text.pdf.PdfWriter;

    public class WelcomeServlet extends HttpServlet {

        private static final String DOCUMENT_LOCATION = "H:\\testPDF.pdf"; // a test pdf on my PC

        @Override
        public void init(ServletConfig config) throws ServletException {
            super.init(config);
        }


        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            PdfReader reader = new PdfReader(DOCUMENT_LOCATION);

            // set some response headers
            response.setHeader("Expires", "0");
            response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
            response.setHeader("Pragma", "public");
            response.setContentType("application/pdf");
            response.setContentLength(baos.size());

            OutputStream os = response.getOutputStream();
            baos.writeTo(os);
            os.flush();
            os.close();

        }
    } 

Why does this only work with PdfStamper? I don't want to do any stamping, I just want to display the PDF in the browser. Is there something I'm missing that basically takes the place of PdfStamper in iText???

回答1:

When you use PdfStamper it is reading in the file from the disk and writing it to baos. When you removed the PdfStamper, baos NEVER GETS WRITTEN TO. So of course, baos is empty, so never actually returns anything.

EDIT: you want to actually do this (the PdfReader is only necessary if you want to modify the PDF):

private static void copy(InputStream is, OutputStream os) throws IOException
{
    byte buffer[] = new byte[8192];
    int bytesRead, i;

    while ((bytesRead = is.read(buffer)) != -1) {
        os.write(buffer, 0, bytesRead);
    }
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

            FileInputStream baos = new FileInputStream(DOCUMENT_LOCATION);

            // set some response headers
            response.setHeader("Expires", "0");
            response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
            response.setHeader("Pragma", "public");
            response.setContentType("application/pdf");
            response.setContentLength(new File(DOCUMENT_LOCATION).length());

            OutputStream os = response.getOutputStream();
            copy(baos, os);
            os.flush();
            os.close();

        }
    } 


回答2:

You aren't using the reader in the second example. I'm not familiar with PdfStamper but I'd guess it uses the reader and thus the contents of your file will be in baos, but not in the second case.



回答3:

If the PDF file is already exists, then you don't have to use itext. You just read data from the file and write it into OutputStream of response.

Here is some code

public class WelcomeServlet extends HttpServlet {

    private static final String DOCUMENT_LOCATION = "H:\\testPDF.pdf"; // a test pdf on my PC

    @Override
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
    }


    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // set some response headers
        response.setHeader("Expires", "0");
        response.setHeader("Cache-Control", "must-revalidate, post-check=0, pre-check=0");
        response.setHeader("Pragma", "public");
        response.setContentType("application/pdf");

        InputStream in = new FileInputStream(DOCUMENT_LOCATION);
        OutputStream out = response.getOutputStream();

        // Copy the bits from instream to outstream
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
           out.write(buf, 0, len);
        }
        in.close();

    }
}