-
1. Re: Serializing large CSV file
niox.nikospara.yahoo.com Jul 2, 2009 8:55 PM (in response to frer)Hello,
I have done something similar: A link that generates a file, then serves its content to the client. In other words a standard download link. NOTE: my use case does not submit the form. The data is gathered in a wizard and after finishing it, the user is provided with a link to download the generated document. Your code seems to contain a messages component, so it may be different use case. Anyway, here is how:
First you need a link that calls an action:
<s:link value="..." action="#{generationBean.download}" />
In the action method:
@Name("generationBean") @AutoCreate @Scope(EVENT) public class GenerationBean { ... public void download() { ... // watch out if it may run in portal!!! HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); response.setContentType(...as appropriate...); response.addHeader("Content-disposition", "attachment; filename=\"THE FILENAME HERE\""); try { ServletOutputStream os = response.getOutputStream(); os.write(...data...); // ITERATE OVER YOUR STRUCTURE AND WRITE DATA, A PIECE AT A TIME // OR GIVE THE ServletOutputStream TO ANYTHING THAT WRITES TO STREAMS os.flush(); os.close(); FacesContext.getCurrentInstance().responseComplete(); // DONT FORGET THIS ONE } catch(IOException ioe) { ... } } ... }
The browser sees the content type and acts accordingly. The JSF mechanism obeys the responseComplete() command and does not execute the render response phase.
-
2. Re: Serializing large CSV file
frer Jul 2, 2009 9:07 PM (in response to frer)Awesome. Exactly what I was looking for.
Thanks
-
3. Re: Serializing large CSV file
frer Jul 2, 2009 11:18 PM (in response to frer)Works well but the only thing is that the attachment is not downloadable but inserted directly in browser. I would like to have a popup where the user chooses to save or open the attachement. My code is the following:
HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse(); response.setContentType("text/csv"); response.addHeader("Content-disposition", "attachment; filename=\"" + fileName + "\""); if(reportTemplate.getIsDaily()) { facadeLocator.getReportTemplateGeneratorDailyFacade().generateCSVReport(reportTemplate, response.getOutputStream()); } else { facadeLocator.getReportTemplateGeneratorHourlyFacade().generateCSVReport(reportTemplate, response.getOutputStream()); } response.getOutputStream().flush(); response.getOutputStream().close(); FacesContext.getCurrentInstance().responseComplete()
where the content is generated by my methods.
How can I force the attachment (even though I have set it in the header)?
Thanks
Francois
-
4. Re: Serializing large CSV file
clerum Jul 2, 2009 11:25 PM (in response to frer)It's a function of the clients browser.
IF you want it downloaded then response.setContentType(
application/octet-stream
);Otherwise specify the correct mime type (
text/csv
) and if clients browser can handle the type then it will be loaded in the browser. -
5. Re: Serializing large CSV file
frer Jul 2, 2009 11:33 PM (in response to frer)Thanks Cody.
Actually the problem was even simpler. I was using a a4j:commandButton for my download link. By using a h:commandButton it solved my problem and now works flawlessly.
Thanks again to both of you.