1
votes

I'm new in stackoverflow thus this is my first post. Please excuse my poor English... I have spent hours on related topics but no anwser met my needs. I'm working on an Address book and I want my users to be able to download a pdf contacts list whenever they want. Everything seems to go well but in fact the client never download the pdf file, though I can see it in the request using the chrome developer tool. Here is my code:

public void doPost( HttpServletRequest request, HttpServletResponse response ) throws IOException, ServletException {

    try {
        Document document = new Document();
        PdfWriter.getInstance( document, response.getOutputStream() );
        document.open();
        document.add( new Paragraph( "You've selected " + request.getParameter("number") + " contacts." ) );

        response.setContentType("application/pdf");
        response.setHeader( "Content-Disposition", "attachment; filename=\"contacts.pdf\"" );

        document.close();
    }
    catch( DocumentException e ) {
        e.printStackTrace();
    }
}

When examining the response, I get something like this:

%PDF-1.4
%����
2 0 obj
>stream
x�+�r
�26S�00S
5 0 obj
>
endobj
6 0 obj
>
endobj
xref
0 7
0000000000 65535 f 
0000000320 00000 n 
0000000015 00000 n 
0000000408 00000 n 
0000000163 00000 n 
0000000459 00000 n 
0000000504 00000 n 
trailer
]/Info 6 0 R/Size 7>>
%iText-5.4.1
startxref
645
%%EOF

Does anyone have the kindness to tell me what's wrong ?

4
Take a look at downloading a PDF that works in dev tools, how does it differ from yours?Abdullah Jibaly
I'm not sure I understand your comment. Could you rephrase ?mnds

4 Answers

1
votes

you should call document.close(), before setting the response headers, here is a detailed example where they are writing explicitly to the outputstream of servlet

hope it helps.

-- [Edit] I ran the same code given in question with itext-2.1.7 but with doGet, works for me, probably the issue is that you are using servlet method which uses POST http request(doPost), while if you are hitting basic url in server directly, that will send a GET request.

you can either override service method, or call doPost from doGet, or submit the same url from a form, or ajax, that will ensure a http Post call.

0
votes

As skywalker pointed out, you are writing directly to the response OutputStream, you need to use an intermediate stream (like a in his linked sample) before setting the response and don't forget to flush() and close() it, in the end.

Also, by setting the content type to application/pdf you are telling the browser to handle such stream as it wants (for instance, it could decide to open the pdf, instead allow you to download it). In order to always force the browser to pop up the download dialog, I'd suggest to use an application/octet-stream content type.

0
votes

I set the post REQUEST header to "application/x-www-form-urlencoded". Isn't it a problem ?

0
votes

I finally resigned in using the post method. It seems to be unusable in this case. Thanks all for your help !