I've been trying to download a file from my server using the
My whole pertinent code is:
My file is a Microsoft Excel one, so I've also tried:
but no success whatsoever.
What happens in the end is that my array of bytes is shown on the browser instead of getting a dialog box asking for saving the file.
Does anyone have a clue to help me out?
Thanks in advance!
DJ aspirant, Engineering undergraduate, Tokusatsus addicted, fond of English language and Asia's, Buddhist, blogger, etc. I'll need to insert all these attributes in a Java class and manage to create methods for handling my overwhelming life
you are trying to download .txt file, then use response.setHeader("Content-Type", "text/plain"); rather than response.setContentType("application/download"); .
and why that last \ [after nomeParaDownload filename] in below line?
response.setHeader("Content-Disposition","attachment;filename=\"" + nomeParaDownload + "\"");
When you use JSF, JSF doesn't run an outputstream like basic J2EE does. Instead it works with a component tree that is then rendered by one of JSF's rendering engines. I'm surprised that you didn't get an Exception, in fact. Something like "Phase violation" or "Response already committed".
Code that generates non-HTML output shouldn't be JSF-based. Put it in a servlet and let your JSF code link to it. Just remember that servlets can't access the FacesContext, so any JSF objects you want to share should be accessed in a non-JSF way - for example, JSF session beans are available to servlets via the usual getSession().getAttribute() functionality.
An IDE is no substitute for an Intelligent Developer.
First of all, thanks for the attempts to help me, Seetharaman and Tim. I'm returning here just now due to the weekend, I stayed outside the office.
One additional information is that, when I mentioned an Excel file, I wanted to say that the data was originally obtained from an Excel file that was parsed and saved into an array of bytes, in TXT format therefore.
Regarding the suggestions given to me:
but the behavior is the same, no download pop-up from the browser, the text is rendered in the browser directly.
Referring to the line
I am specifying the name of the file that users should download, so that in the pop-up window reads something like "Where do you wish to save 'marcos.txt'?"
Thanks for the info about the inability to run non-JSF code directly from a JSF context. As you recommended, I tried to use a raw Servlet, I created a servlet class wherein I created the following method:
The aim was to create and use an OutputStream object from a non-JSF context as you suggested, so that all the output job is done and then the JSF context returns to its normal operation, after the whole method outputFile() is finished.
By doing that, I ended up having to work with 2 different response objects in my code, one from
and the other obtained from facesContext servlet
I've tried to deal with it, but I began running into other types of Exceptions, including NullPoiterException, then I quit following that path.
Tim, do you still suggest me following that track, or maybe doing it differently, still counting on raw Servlets? Actually, another question is valid, asking that to everybody:
Is there a way to produce a pop-up window in the browser from JSF code? Would there be anything like a JSF component or a specific way of dealing with the facesContext Servlet to produce such a pop-up window?
JSF cannot call servlets. In fact, servlets cannot call servlets. You can forward from JSF/JSP/servlet to JSF/JSP/servlet, but no call-and-return. So only one Request object is involved here.
What I normally do is post a hyperlink on a JSF page to get the document and that hyperlink is the URL of the servlet. By using the "target=" attribute, the document can be made to open in a separate window or downloaded to a local file. Although in Internet Explorer there's an additional constraint. Ever since Microsoft lost the lawsuit on embedded content, IE has been forbidden from opening PDFs, Excel, Word and other documents in IE windows. So instead an actual stand-alone copy of Office or Adobe Reader has to be launched by IE.
You pretty much have to do the hyperlink route. HTTP only allows one document to be returned per request. That document can be an HTML webpage (JSF or otherwise), or it can be an Excel spreadsheet, but no one URL request can return both at the same time. ZIPfiles don't count.
I'll try to follow your directions and check to see how long I can go, hopefully till the end of the tunnel
PS: I liked your sentence:
A lot the of modern-day software development platforms are designed to permit parcelling out work to those with the best aptitude for it. A lot of modern-day business is predicated on making one person do all the work, regardless of aptitude.
I've realized that a simple hyperlink would not work for me, given that my file is produced dynamically, it is not stored on the server prior to clicking on the hyperlink, so that I can just retrieve it. I do a need a method to perform lots of operations, generating the file, and only then making it available for download. Methods are bound to buttons, so I'll probably need one in my scenario.
I'm trying to avoid creating a button and a hyperlink to perform the operations separately. It is a lot convenient to fire both things from the same action, such as the click of a button.
Do you still have any further ideas? May anyone else suggest something also?
No. WEB servers are NOT FILE servers. You cannot code a filename in a URL and retrieve a file from the server. You have to either have the file stored as a fixed resource in the WAR and retrieve it via an HTTP URL or you have to implement an application function to generate the document dynamically. In some cases that may end up with you creating a temporary file on the server and then having servlet logic copy the content of that temporary file to the HttpResponse stream.
Please note that you should NEVER write files in the WAR itself. If you need a temporary file, use the java.io tempfile method to create one. The webapp server will provide a safe directory location and give you a File object to access it.