Pdf file not loading properly created by the servl

2019-03-06 11:44发布

问题:

Friends, I am have implemented a jsp form which takes inputs like title, description and content of the pdf file. When the jsp form is submitted, the pdf is created using itext with the help of the servlet called 'pdfGenServlet.java'.

my jsp form is

<form action="pdfGenServlet1" method="get" enctype="application/x-www-form-urlencoded">
                <!-- input notes title-->
                <div class="form-group">
                    <div class="input-group">
                        <input type="text" class="form-control" placeholder="Title of the notes" name="title">
                    </div>
                </div>
                <!-- input notes description-->
                <div class="form-group">
                    <div class="input-group">
                        <input type="text" class="form-control" placeholder="Enter short description" name="description">
                    </div>
                </div>

                <div class="form-group">
                  <textarea name="content" id="myEditor"></textarea>

                 <div id="button-panel" class="panel panel-default">
                      <p>
                          <button type="submit" class="btn btn-primary "><span class="glyphicon glyphicon-plus"></span><strong> Create Note</strong></button>
                          <button class="btn btn-primary" type="reset"><strong>Reset</strong></button>
                      </p><!-- buttons -->
                 </div><!-- panel Button -->

                </div>

            </form> 

The servlet 'pdfGenServlet.java'

//imports for itext
import java.io.FileOutputStream;
import java.io.StringReader;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Font;
import com.itextpdf.text.Font.FontFamily;
import com.itextpdf.text.Document;
import com.itextpdf.text.PageSize;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.html.simpleparser.HTMLWorker; // deprecated
import com.itextpdf.text.pdf.PdfWriter;

//servlet imports
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

//File handling and java util
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.util.Date;


@WebServlet("/pdfGenServlet1")
public class pdfGenServlet1 extends HttpServlet {
    private static final long serialVersionUID = 1L;

/**
 * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
 */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    try {

        //Font for using with itext
        Font bfBold18 = new Font(FontFamily.TIMES_ROMAN, 18, Font.BOLD, new BaseColor(0, 0, 0)); 
        Font bfBold12 = new Font(FontFamily.TIMES_ROMAN, 12, Font.BOLD, new BaseColor(0, 0, 0)); 

        String title = request.getParameter("title");
        String description = request.getParameter("description");
        String notes_content = request.getParameter("content");
        Date date = new Date();

        Document document = new Document(PageSize.A4);
        PdfWriter.getInstance(document, new FileOutputStream("C://BEProject//PreparedNotes//testpdf1.pdf"));
        HTMLWorker htmlWorker = new HTMLWorker(document);
        document.open();

        document.addAuthor("Real Gagnon");
        document.addCreator("Real's HowTo");
        document.addSubject("Thanks for your support");
        document.addCreationDate();
        document.addTitle("Please read this");

        //
        document.addCreationDate();
        document.add(new Paragraph("TITLE: ", bfBold18));
        document.add(new Paragraph(title,bfBold12));
        document.add(new Paragraph("\n"));
        document.add(new Paragraph(String.format("Created on: " + date.toString())));
        document.add(new Paragraph("DESCRIPTION: ", bfBold18));
        document.add(new Paragraph(description,bfBold12));
        document.add(new Paragraph("\n"));

        htmlWorker.parse(new StringReader(notes_content));
        // step 5
        document.close();

        response.setHeader("Content-disposition", "attachment; filename= testpdf1.pdf");

        response.setContentType("application/pdf");

    } catch (DocumentException e) {

        e.printStackTrace();
    }




}

} Please try the code urself. You'll see the pdf file created downloads automatically but when opened it show loading but doesnt loads like this

When the same file made at directory displayed in pdfGenServlet at 'C://BEProject//PreparedNotes//testpdf1.pdf' . When the testpdf1.pdf is opened manually it opens properly. Please help

回答1:

You create a PDF on your local disk and you set some headers that are sent to the browser. You do not send any bytes to the browser, hence you should not expect to see anything in your browser. This is consistent with the behavior you describe.

In another answer, somebody tells you to write the PDF bytes to the HttpServletResponse. The most simple way to do this, is to follow the example from the book I wrote about iText, more specifically, the Hello example:

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());
    }
}

You can try this example here.

In an ideal world, this would work for all browsers. Unfortunately, not all browsers are created alike, hence you may want to code in a more defensive way by following the PdfServlet example:

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();
        // if you also want to write these bytes to a file, add:
        OutputStream fos = new FileOutputStream(pathToFile);
        baos.writeTo(fos);
        fos.flush();
        fos.close();
    }
    catch(DocumentException e) {
        throw new IOException(e.getMessage());
    }
}

You can try this servlet here. As you can see, we now create the file in memory first. We do so, so that we can set the header for the content length (some browsers require this). I've also set some other headers that may not be necessary, but that were added to my example over the years based on feedback of thousands of iText users.