Filedownload"

From Documentation
 
(7 intermediate revisions by 5 users not shown)
Line 1: Line 1:
 
{{ZKComponentReferencePageHeader}}
 
{{ZKComponentReferencePageHeader}}
  
= Fileupload =
+
= Filedownload =
  
 
*Demonstration:  [http://www.zkoss.org/zkdemo/file_handling/file_download File Downpload ]
 
*Demonstration:  [http://www.zkoss.org/zkdemo/file_handling/file_download File Downpload ]
Line 10: Line 10:
 
= Employment/Purpose =
 
= Employment/Purpose =
  
<javadoc>org.zkoss.zul.Filedownload</javadoc> provides provides a set of utilities to prompt a user for downloading a file from the server to the client.
+
<javadoc>org.zkoss.zul.Filedownload</javadoc> provides a set of utilities to prompt a user for downloading a file from the server to the client.
  
 
Notice that <javadoc>org.zkoss.zul.Filedownload</javadoc> is not a component. Rather, it is a collection of utilities for file download.
 
Notice that <javadoc>org.zkoss.zul.Filedownload</javadoc> is not a component. Rather, it is a collection of utilities for file download.
  
Unlike the <tt>iframe</tt> component that displays the file in the browser window, a file download dialog is shown at the browser if one of the <tt>save</tt> methods is called. Then, the user can specify the location in his local file system to save the file.
+
Unlike the <code>iframe</code> component that displays the file in the browser window, a file download dialog is shown at the browser if one of the <code>save</code> methods is called. Then, the user can specify the location in his local file system to save the file.
  
 
[[Image:10000000000002AF000001BB582C2DD7.png]]
 
[[Image:10000000000002AF000001BB582C2DD7.png]]
Line 30: Line 30:
 
</button>
 
</button>
 
</source>
 
</source>
 +
 +
 +
= The Resumable Download =
 +
 +
{{ZK EE}}
 +
 +
In certain situations, you might prefer to generate an URL that can be used even if the desktop becomes invalid. For example, you want to allow users to use a download manager (such as <code>wget</code> and <code>DownThemAll</code>). Another example is related to the blocking feature found in some browsers -- which confirm the download with the user and causes the page to reload (and then the previous desktop is lost).
 +
 +
To solve this, you have to use the so-called resumable download. By resumable we mean the user can bookmark the URL and download it later (and even resume the download in the middle). On the other hand, the download URL of the <code>save</code> method becomes obsolete as soon as the desktop (or session) is gone.
 +
 +
To use resumable download, you have to invoke the <code>saveResumable</code> method of <javadoc>org.zkoss.zkmax.zul.Filedownload</javadoc> instead of <code>save</code> as depicted below:
 +
 +
<source lang="xml">
 +
<window title="Save Resumable" border="normal">
 +
<button label="download"
 +
onClick='Filedownload.saveResumable("foo.txt", "text/plain", null)'/>
 +
</window>
 +
</source>
 +
 +
Then, the URL generated by <code>saveResumable</code> can be copied to the download manager the user prefers.
 +
 +
== Control Resumable Download ==
 +
Since the resumable download can be used in any session or without any session, or with a different client (such flashget), you might want to limit the download under certain condition. There are two library properties that can control the number of allowed resumable downloads.
 +
 +
* <code>org.zkoss.zk.download.resumable.lifetime</code>
 +
** Specifies when the download URL will be expired (unit: second).
 +
** Default: 14400 (i.e., 4 hours).</dd>
 +
* <code>org.zkoss.zk.download.resumable.maxsize</code>
 +
** <dd>Specifies the maximal allowed number of resumable downloads.
 +
(( Default: 4096.
 +
 +
If you want more advanced control, you can implement <javadoc>org.zkoss.zkmax.zul.FiledownloadListener</javadoc> and specify it in a library property called <code>org.zkoss.zkmax.zul.FiledownloadListener.class</code>. For examle, in <code>zk.xml</code>, you can do:
 +
 +
<source lang="javascript">
 +
<library-property>
 +
  <name>org.zkoss.zkmax.zul.FiledownloadListener.class</name>
 +
  <value>com.foo.MyDownloadListener</value>
 +
</library-property>
 +
</source>
 +
 +
=Handling download target and window unload=
 +
Triggering a file download in the main context of a ZK page can cause the client-engine to terminate while the page is still open.
 +
 +
Refer to the [[ZK_Developer%27s_Reference/UI_Patterns/File_Upload_and_Download|Developer Reference]] guide for in-depth details.
  
 
= Limitation of IE 6/7/8 =
 
= Limitation of IE 6/7/8 =
  
With this approach, Internet Explorer 6, 7 and 8<ref>Internet Explorer 9 and other browsers all work fine without this limitation.</ref> will show up an warning message on top of the browser as shown below ("To help protect your security, Internet Explorer...").
+
With this approach (<javadoc>org.zkoss.zul.Filedownload</javadoc>), Internet Explorer 6, 7, and 8<ref>Internet Explorer 9 and other browsers all work fine without this limitation.</ref> will show up a warning message on top of the browser as snapshot below ("To help protect your security, Internet Explorer...").
  
 
[[File:IePreventDownload.png]]
 
[[File:IePreventDownload.png]]
  
If the user allows the download (right click and select <tt>Download File...</tt>), IE will eventually reload the page. It means the whole content of the page is reloaded and the downloading does not take place. And, the user have to click the download again. It is a tedious user experience.
+
If a user allows the download (right-click and select <code>Download File...</code>), IE will eventually reload the page. It means the whole content of the page is reloaded and the downloading does not take place. And, the user has to click the download button or link again. It is a tedious user experience.
  
To work around it, you usually have to prepare another page for real download, and then use FORM submit to redirect to the page for real download. For example,
+
To work around it, we have to prepare another page for real download, and then use FORM submit, instead of invoking <javadoc>org.zkoss.zul.Filedownload</javadoc>, to redirect to the page for real download. For example,
  
 
<source lang="xml">
 
<source lang="xml">
 
<!-- download.zul: the page that guides users to download -->
 
<!-- download.zul: the page that guides users to download -->
<h:form xmlns:h="native" action="real-download.jsp" target="_blank">
+
<h:form xmlns:h="native" action="real-download.jsp" target="_blank"> <!-- a form -->
<button label="Download" type="submit"/>
+
<button label="Download" type="submit"/> <!-- use a submit button -->
 
</h:form>
 
</h:form>
 
</source>
 
</source>
  
And, the page for real download could be implemented in, say, JSP or a servlet by use of <javadoc method="write(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.zkoss.util.media.Media, boolean, boolean)">org.zkoss.web.servlet.http.Https</javadoc> and <javadoc>org.zkoss.util.media.AMedia</javadoc>. For example,
+
And, the page for real download could be implemented with, say, JSP or a servlet. ZK provides utilities to simplify the task: <javadoc method="write(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, org.zkoss.util.media.Media, boolean, boolean)">org.zkoss.web.servlet.http.Https</javadoc> and <javadoc>org.zkoss.util.media.AMedia</javadoc>. For example,
  
 
<source lang="xml">
 
<source lang="xml">
 
<%-- real-download.jsp: the page really downloads the file to response --%>
 
<%-- real-download.jsp: the page really downloads the file to response --%>
  
<%@ page import="org.zkoss.web.servlet.http.Https, org.zkoss.util.media.AMedia, java.io.*" %>
+
<%@ page import="org.zkoss.web.servlet.http.Https, org.zkoss.util.media.AMedia" %>
 
<%
 
<%
 
Https.write(request, response,
 
Https.write(request, response,
Line 62: Line 106:
 
</source>
 
</source>
  
If the file/content to download is selectable, you could enhance <tt>download.zul</tt> in the above example by adding more input components inside HTML FORM. For example,
+
If the user could input more information to select the file to download, we could enhance <code>download.zul</code> in the above example by adding more input components inside HTML FORM. For example,
  
 
<source lang="xml">
 
<source lang="xml">
Line 75: Line 119:
 
== Side Effect: Chrome and Safari ==
 
== Side Effect: Chrome and Safari ==
  
This HTML FORM approach works fine under all Internet Explorer and Firefox. However, it has another unpleasant effect under Chrome and Safari: it keeps additional blank browser window after downloaded. Thus, it is better to detect the browser first and apply the HTML Form approach only if it is Internet Explorer.
+
This HTML FORM approach works fine under all Internet Explorer and Firefox. Unfortunately, it has another unpleasant side effect under Chrome and Safari: it opens an additional blank browser window (so the user has to close it manually). Thus, it is better to detect the browser first and apply the HTML Form approach only if it is Internet Explorer.
  
<source lang="xml" high="3">
+
<source lang="xml" highlight="3">
 
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
 
<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
 
<h:form xmlns:h="native" action="real-download.jsp" target="_blank"
 
<h:form xmlns:h="native" action="real-download.jsp" target="_blank"
Line 89: Line 133:
 
</blockquote>
 
</blockquote>
  
= The Resumable Download =
 
 
{{ZK EE}}
 
 
In certain situations, you might prefer to generate an URL that can be used even if the desktop becomes invalid. For example, you want to allow users to use a download manager (such as <code>wget</code> and <code>DownThemAll</code>). Another example is related to the blocking feature found in some browsers -- which confirm the download with the user and causes the page to reload (and then the previous desktop is lost).
 
 
To solve this, you have to use the so-called resumable download. By resumable we mean the user can bookmark the URL and download it later (and even resume the download in the middle). On the other hand, the download URL of the <code>save</code> method becomes obsolete as soon as the desktop (or session) is gone.
 
 
To use resumable download, you have to invoke the <code>saveResumable</code> method of <javadoc>org.zkoss.zkmax.zul.Filedownload</javadoc> instead of <code>save</code> as depicted below:
 
 
<source lang="xml">
 
<window title="Save Resumable" border="normal">
 
<button label="download"
 
onClick='Filedownload.saveResumable("foo.txt", "text/plain", null)'/>
 
</window>
 
</source>
 
 
Then, the URL generated by <code>saveResumable</code> can be copied to the download manager the user prefers.
 
 
== Control Resumable Download ==
 
Since the resumable download can be used in any session or without any session, or with a different client (such flashget), you might want to limit the download under certain condition. There are two library properties that can control the number of allowed resumable downloads.
 
 
* <code>org.zkoss.zk.download.resumable.lifetime</code>
 
** Specifies when the download URL will be expired (unit: second).
 
** Default: 14400 (i.e., 4 hours).</dd>
 
* <code>org.zkoss.zk.download.resumable.maxsize</code>
 
** <dd>Specifies the maximal allowed number of resumable downloads.
 
(( Default: 4096.
 
 
If you want more advanced control, you can implement <javadoc>org.zkoss.zkmax.zul.FiledownloadListener</javadoc> and specify it in a library property called <code>org.zkoss.zkmax.zul.FiledownloadListener.class</code>. For examle, in <code>zk.xml</code>, you can do:
 
 
<source lang="javascript">
 
<library-property>
 
  <name>org.zkoss.zkmax.zul.FiledownloadListener.class</name>
 
  <value>com.foo.MyDownloadListener</value>
 
</library-property>
 
</source>
 
  
 
=Version History=
 
=Version History=
 
{{LastUpdated}}
 
{{LastUpdated}}
{| border='1px' | width="100%"
+
{| class='wikitable' | width="100%"
 
! Version !! Date !! Content
 
! Version !! Date !! Content
 
|-
 
|-

Latest revision as of 02:55, 30 November 2022

Filedownload

Employment/Purpose

Filedownload provides a set of utilities to prompt a user for downloading a file from the server to the client.

Notice that Filedownload is not a component. Rather, it is a collection of utilities for file download.

Unlike the iframe component that displays the file in the browser window, a file download dialog is shown at the browser if one of the save methods is called. Then, the user can specify the location in his local file system to save the file.

10000000000002AF000001BB582C2DD7.png

<button label="Download">
	<attribute name="onClick">{
		java.io.InputStream is = desktop.getWebApp().getResourceAsStream("/test/download.html");
		if (is != null)
			Filedownload.save(is, "text/html", "download.html");
		else
			alert("/test/download.html not found");
	}
	</attribute>
</button>


The Resumable Download

  • Available for ZK:
  • http://www.zkoss.org/product/zkhttp://www.zkoss.org/whyzk/zkeeVersion ee.png

In certain situations, you might prefer to generate an URL that can be used even if the desktop becomes invalid. For example, you want to allow users to use a download manager (such as wget and DownThemAll). Another example is related to the blocking feature found in some browsers -- which confirm the download with the user and causes the page to reload (and then the previous desktop is lost).

To solve this, you have to use the so-called resumable download. By resumable we mean the user can bookmark the URL and download it later (and even resume the download in the middle). On the other hand, the download URL of the save method becomes obsolete as soon as the desktop (or session) is gone.

To use resumable download, you have to invoke the saveResumable method of Filedownload instead of save as depicted below:

<window title="Save Resumable" border="normal">
	<button label="download"
	onClick='Filedownload.saveResumable("foo.txt", "text/plain", null)'/>
</window>

Then, the URL generated by saveResumable can be copied to the download manager the user prefers.

Control Resumable Download

Since the resumable download can be used in any session or without any session, or with a different client (such flashget), you might want to limit the download under certain condition. There are two library properties that can control the number of allowed resumable downloads.

  • org.zkoss.zk.download.resumable.lifetime
    • Specifies when the download URL will be expired (unit: second).
    • Default: 14400 (i.e., 4 hours).
  • org.zkoss.zk.download.resumable.maxsize
    • Specifies the maximal allowed number of resumable downloads.

(( Default: 4096.

If you want more advanced control, you can implement FiledownloadListener and specify it in a library property called org.zkoss.zkmax.zul.FiledownloadListener.class. For examle, in zk.xml, you can do:

<library-property>
  <name>org.zkoss.zkmax.zul.FiledownloadListener.class</name>
  <value>com.foo.MyDownloadListener</value>
</library-property>

Handling download target and window unload

Triggering a file download in the main context of a ZK page can cause the client-engine to terminate while the page is still open.

Refer to the Developer Reference guide for in-depth details.

Limitation of IE 6/7/8

With this approach (Filedownload), Internet Explorer 6, 7, and 8[1] will show up a warning message on top of the browser as snapshot below ("To help protect your security, Internet Explorer...").

IePreventDownload.png

If a user allows the download (right-click and select Download File...), IE will eventually reload the page. It means the whole content of the page is reloaded and the downloading does not take place. And, the user has to click the download button or link again. It is a tedious user experience.

To work around it, we have to prepare another page for real download, and then use FORM submit, instead of invoking Filedownload, to redirect to the page for real download. For example,

<!-- download.zul: the page that guides users to download -->
<h:form xmlns:h="native" action="real-download.jsp" target="_blank"> <!-- a form -->
	<button label="Download" type="submit"/> <!-- use a submit button -->
</h:form>

And, the page for real download could be implemented with, say, JSP or a servlet. ZK provides utilities to simplify the task: Https.write(HttpServletRequest, HttpServletResponse, Media, boolean, boolean) and AMedia. For example,

<%-- real-download.jsp: the page really downloads the file to response --%>

<%@ page import="org.zkoss.web.servlet.http.Https, org.zkoss.util.media.AMedia" %>
<%
	Https.write(request, response,
		new AMedia("B1896797.pdf", null, null,
			application.getResourceAsStream("/test2/B1896797.pdf")),
		true/*download*/, false);
%>

If the user could input more information to select the file to download, we could enhance download.zul in the above example by adding more input components inside HTML FORM. For example,

<h:form xmlns:h="native" action="real-download.jsp" target="_blank">
	<datebox name="when"/>
	<button label="Download" type="submit"/>
</h:form>

Notice we have to specify the name property such that its value will be sent with the given name. For more information of using HTML FORM, please refer to ZK Developer's Reference/Integration/Use ZK in JSP#HTML_Form:ZK Developer's Reference: HTML Form.

Side Effect: Chrome and Safari

This HTML FORM approach works fine under all Internet Explorer and Firefox. Unfortunately, it has another unpleasant side effect under Chrome and Safari: it opens an additional blank browser window (so the user has to close it manually). Thus, it is better to detect the browser first and apply the HTML Form approach only if it is Internet Explorer.

<?taglib uri="http://www.zkoss.org/dsp/web/core" prefix="c"?>
<h:form xmlns:h="native" action="real-download.jsp" target="_blank"
 if="${c:browser('ie')}">
...

  1. Internet Explorer 9 and other browsers all work fine without this limitation.


Version History

Last Update : 2022/11/30


Version Date Content
     



Last Update : 2022/11/30

Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.