voyent
How to implement a File Download  XML
Forum Index -> General Help
Author Message
Newlukai

Joined: 29/Nov/2006 00:00:00
Messages: 125
Offline


Hi there,

I got a problem implementing a file download in my application. So I read some threads and I think there are three ways to implement a File Download:

1. Use HttpServletResponse in backing bean
This is not able with ICEfaces, since it uses AJAX.

Because you can't use HttpServletResponse there is only the possibility to write a custom servlet which uses the HttpServletResponse. After creating this servlet you have to specify how to address it in "web.xml", like this:

Code:
<servlet>
   <servlet-name>downloadServlet</servlet-name>
   <servlet-class>com.bla.DownloadServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
 </servlet>
 
 <servlet-mapping>
   <servlet-name>downloadServlet</servlet-name>
   <url-pattern>/downloadFile</url-pattern>
 </servlet-mapping>


You have now two ways to redirect to this servlet from your bean.

2. <WhateverContextYouUse>.getExternalContext().redirect("downloadFile");
Works fine. The problem is, that if you use a commandLink, your application freezes. The AJAX bridge isn't started until you refresh the page. And if you think you could use target="_blank" ... you can't. It doesn't work.
Therefore you could use an outputLink. Didn't try this, since I need to invoke an action. So the outputLink is useless to me.

3. Use JavascriptContext.addJavascriptCall()
Just send an JS "open.window" call with the URL of your servlet and it does, what you expected the commandLink to do. It opens a new window/tab and in this window/tab your servlet does whatever you want it to do.

My problem now is:
1: Doesn't work with AJAX. OK. I tried

2: Doesn't work. I need to invoke an action so I have to use the commandLink, which freezes my application. My last possibility was

3: But this one seems to be buggy. It just doesn't work. Whatever I do, the JS I specify in my backing bean is not executed on client side.

Is there another possibility to send a file to the browser? Or will the mentioned JIRA issue be fixed?

Thanks in advance
Newlukai
michael.thiem


Joined: 04/Jun/2007 00:00:00
Messages: 704
Offline


Hi,

I don't think that the ice:outputLink is completely useless when implementing a file download. You can create a download feature in your application if you move the code for downloading the file into your servlet. You shouldn't need any javascript at all. Here's a simple example of how a download servlet (for csv based files) might look like:

Code:
 	public void doPost(HttpServletRequest req, HttpServletResponse response) {
 
 		HttpSession session = req.getSession(false);
 		if (session != null) {			
 			String filename="some_file_path/some_file.csv";	
                        response.setContentType("text/comma-separated-values");
                        response.setHeader("Content-Disposition", "attachment;filename=\""
 				+ fileName + "\"");
 			download(response);
 		}		
 	}
 
 	private void download(HttpServletResponse response) {
 		BufferedWriter ow = null;
 		try {
 			BufferedReader br = new BufferedReader(new FileReader(filePath));
 			String line = br.readLine();
 
 			ow = new BufferedWriter(response.getWriter());
 			while (line != null) {
 				ow.write(line);
 				ow.newLine();
 				line = br.readLine();
 			}
 			ow.flush();
 		} catch (Exception exception) {
 			exception.printStackTrace();
 		} finally {
 			if (ow != null) {
 				try {
 					ow.close();
 				} catch (IOException ioe) {
 					ioe.printStackTrace();
 				}
 			}
 		}
 	}
 


In your jsp file you can then call the servlet via the outputLink component like:

Code:
    <ice:outputLink value="/download">
       <ice:outputText value="download csv file"/>
    </ice:outputLink>	
 


Assuming you have a servlet definition like:

Code:
 <servlet>
    <servlet-name>downloadServlet</servlet-name>
    <servlet-class>test.DownloadServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
 </servlet>		
 	
 <servlet-mapping>
    <servlet-name>downloadServlet</servlet-name>
    <url-pattern>/download</url-pattern>
 </servlet-mapping> 
 


This should open the default window/application associated with this kind of file extension.

Regards,
Michael
Newlukai

Joined: 29/Nov/2006 00:00:00
Messages: 125
Offline


Thanks. I tried to use an outputLink and it works.

But let me explain why I can't use this. The files my application provides and stores are whether managed by a DB or are saved on a file system. So I have to read the requested file from DB/file system and write it to a temp directory for the servlet.
I _could_ move the code which manages the two file sources to the servlet, but that would not be what I call good software design.

So the possibilities I mentioned would really be fine. Whether use a commandLink or JavascriptContext. But they are both broken. The target attribute of commandLink doesn't what it should do, and JavascriptContext doesn't do anything.

Perhaps I should mention that I use 1.7.0 beta1 on a JBoss 4.2.2 with Seam 2.0.1.
cfalba

Joined: 04/Oct/2007 00:00:00
Messages: 46
Offline


Hi,
I tried this solution with the outputlink, and it opens the window to save the file, but then my applicatin freezes, I click on any component and don't respond. Do you know why is this happening?

Thanks
alexandre1980

Joined: 10/Sep/2008 00:00:00
Messages: 125
Offline


did you solve this ?
michelle2

Joined: 14/Nov/2007 00:00:00
Messages: 449
Offline


Newlukai wrote:
the requested file from DB/file system and write it to a temp directory for the servlet.
 



Why?

retrieve it as a byteArrayOutputStream, convert the bao to a servletOutputStream

If I follow you correctly you don't need to store it anywhere temperally.

We use this methods to create pdf's all the time, but the principle is the same
[Email]
 
Forum Index -> General Help
Go to:   
Powered by JForum 2.1.7ice © JForum Team