wood burning stoves 2.0*
The moose likes Servlets and the fly likes How Do You Send text/html After Sending A ServletOutputStream File To The Client? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Servlets
Bookmark "How Do You Send text/html After Sending A ServletOutputStream File To The Client?" Watch "How Do You Send text/html After Sending A ServletOutputStream File To The Client?" New topic
Author

How Do You Send text/html After Sending A ServletOutputStream File To The Client?

Bob Nedwor
hangman
Ranch Hand

Joined: Aug 17, 2005
Posts: 215

I have a cool Servlet (using commons fileUpload, etc) that gets a file from the user, does some processing and sends it back. But after they save the file, I want to display a message in their browser. Thanks for any suggestions. This is what I have tried and it does not seem to be working:



The HTML does not get displayed. The file still gets downloaded, but the browser only shows what it did prior to the "Save As" dialogue box.
Thanks so much for any hints.
[ May 29, 2006: Message edited by: Bob Nedwor ]

Bob N
SCJP - 1.4
SCJD - (B&S) Used 1.5 And It Runs On Solaris10
SCWCD - Thanks to HFSJ!!
Vince HW Chan
Greenhorn

Joined: Aug 16, 2005
Posts: 5
Do you find any exception throw during the process, like "The header already sent"?? Just think the response has already sent header (contentType) before the file is sent to user, so your action (response.setContentType) is ignored.

Could you try to redirect the user to another page once the download is completed and show the message on that page? I have no idea if this way can really work as it also required HTTP-header to be changed.
Bob Nedwor
hangman
Ranch Hand

Joined: Aug 17, 2005
Posts: 215

Thanks, Yes you are right. I cannot set the Content-Type once it has already been set, or once some bytes have already been written to the output stream. (I never did get an exception), but I just saw this in my K&B "HF Servlets & JSPs" book. I also saw that I cannot do a re-direct once bytes have been written to the output stream, so unfortunately, that suggestion won't work either...

There must be a way to do it...

Hmmm. I guess I will have to read further into my K&B "HF Servlets & JSPs" book.

Thanks for any further suggestions.
Charles Lyons
Author
Ranch Hand

Joined: Mar 27, 2003
Posts: 836
But why do you want to send a file and an HTML page in one response? That sounds mighty unwise to me. Each response can only have one Content-Type MIME header, so all your data needs to be one type or the other, not both. Plus, what do you expect a browser to do with a binary file followed by an HTML fragment... note the response is effectively malformed as you've got binary data, then an XML document. An XML parser isn't going to like that!

It looks to me like what you're trying to do is effectively an e-mail thing: send an HTML body with a file attachment. But a browser will either offer to download the content you're sending (by presenting the user with a download dialog) or it will render the Web page. It cannot, and should not, do both (unlike e-mail which does this most of the time).

You should choose which one you actually want to happen. If the answer is both, you would need to return the HTML first, and have a hyperlink in that page to the resource which could be downloaded (or execute a client-side redirect using refresh metadata or JavaScript). This means setting up an extra servlet and possibly storing data on the server.

Otherwise you would need to pre-warn the user that after uploading has completed, their file will be send back to the them automatically. You'll then get a seamless file submission and download in, apparently, one step.


Charles Lyons (SCJP 1.4, April 2003; SCJP 5, Dec 2006; SCWCD 1.4b, April 2004)
Author of OCEJWCD Study Companion for Oracle Exam 1Z0-899 (ISBN 0955160340 / Amazon Amazon UK )
Bob Nedwor
hangman
Ranch Hand

Joined: Aug 17, 2005
Posts: 215

Thanks, Charles. I am pretty new with Servlets. Most of what you said makes sense. But the rest of it I will have to think about...

I am sure you have been to a website where you have downloaded something (because the "Save As" dialogue box of your browser comes up), then after your are finished downloading it, you get some type of confirmation in your browser (like "Thanks for trying our product" or something like that).

This all I am tring to do. For now, I will take out stuff about the 2nd setContentType and sending HTML, to ensure that the response is not effectively malformed and at least the download works 100%.

Thanks so much for any further hints (or some code samples that demostrate one of your solutions. )
Charles Lyons
Author
Ranch Hand

Joined: Mar 27, 2003
Posts: 836
I am sure you have been to a website where you have downloaded something (because the "Save As" dialogue box of your browser comes up), then after your are finished downloading it, you get some type of confirmation in your browser (like "Thanks for trying our product" or something like that).
Probably the way they do this is to use:contained inside the <head> for the page. This causes the browser to redirect (after 1 second) to the url "xxx"; if you set xxx to be the address of your resource, this would first display the HTML page, then cause the browser to present the download window - this assumes the Content-Type returned from that URL isn't directly renderable in the browser, such as text/plain or text/html (or certain XML, XHTML or image formats are), otherwise that page will be displayed rather than the download dialog window.

You can try this for yourself without even requiring a Web server:I've used "file.jar" as the resource because all browsers will download that, but you can choose whatever you need (bear in mind that Web pages and images will be displayed and not presented with a download window).

Alternatively, you can use client-side scripting (e.g. JavaScript) to do the redirection.

Hope that helps.
Bob Nedwor
hangman
Ranch Hand

Joined: Aug 17, 2005
Posts: 215

Thanks so much, Charles. Because of your help, I am getting closer. I (think that I) took your advice and added the suggested line to my index.html, but now the problem is that it just goes to the new confirmation page, after one second, without giving the user the chance to upload the original file to be processed by the servlet.. Here is the new index.html :



and here is the new confirmation page(confirm.html):




and here is my DD:



[ May 30, 2006: Message edited by: Bob Nedwor ]
Charles Lyons
Author
Ranch Hand

Joined: Mar 27, 2003
Posts: 836
What you want to do is to have the index.html upload form the same as it used to be (with no refresh).

Then have your servlet store the results of its processing in a file (either publicly accessible, or use a servlet as a proxy to read the private file and forward its contents to the client). Alternatively, you can store it all in memory, but then you'll definitely need a servlet to access it and copy it to the client.

Add the refresh meta tag to your confirm.html page, and use the URL of the file/servlet...

So now the client sees the index.html form, submits it, your servlet returns the confirm page's contents, and the confirm page refreshes after 1 second to the location of the new file, causing a download window to pop up.

So for example, the confirmation page becomes:Note the upload12345 URL would be different for each upload, so your servlet executed after form submission would need to create a unique new file (e.g. based on the date/time of upload or a client ID), and when returning the confirm page, the servlet needs to edit the "upload12345" to convert it to the correct address of the previously created file.

Your main problem will be to decide whether to use a file or store the data in memory, and how to create a servlet which can return that data (if the file isn't publicly accessible).
Bob Nedwor
hangman
Ranch Hand

Joined: Aug 17, 2005
Posts: 215

Thanks so much, Charles! Yes, now I see what you are saying. Instead of one servlet doing everything, break up it into 2 servlets, driven by two separate HTML calls (the 2nd of which the user never really sees)...

I think I can do that...

Thanks so much. I will let you know when I finish.
Bob Nedwor
hangman
Ranch Hand

Joined: Aug 17, 2005
Posts: 215

Done! Actually I still only needed the one servlet!

Thanks so much Charles.
Charles Lyons
Author
Ranch Hand

Joined: Mar 27, 2003
Posts: 836
Excellent... great to hear it worked in the end, and thanks for the follow-up!
Ed Ward
Ranch Hand

Joined: Jan 30, 2006
Posts: 147
I have a cool Servlet



Don't we all.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: How Do You Send text/html After Sending A ServletOutputStream File To The Client?